User:Siriuswapnil/Blogs/week3

With 2 PRs published, the journey has been wonderful so far. One learning from this week’s work is how important it is to maintain proper documentation. Tim rightly said,

There are countless extremely good software developers on the planet. However, what really helps to stand out among them is the ability to properly document each and every step which can not only help you understand code better, as well as provide others immense help in reading your code.

The coming week’s targets are as follows:

  1. Finalizing on the documentation for writing SPARQL queries and getting GeoJSON output files.
  2. Working on making the coordinate visuals more appealing. They currently just show as a simple dot. Have to introduce modifications into the GeoJSON file to include additional metadata.

17/06 : Task 1 complete. Finished Blog-Post and published to Medium. Moving onto styling.

23-06 : Task 2 complete: Finished BlogPost on Styling and displaying overlays on maps.

Styling Markers and creating overlays from GeoJSON data

edit


Styling the markers

edit

The markers displayed on Openlayers are small blue dots. They are not very informative, neither do they help to differentiate between different types of markers. Hence, styling them is necessary.

Adding style features to the markers

edit

Markers can be styled using a stylefunction which is a built-in method provided by Openlayers. We include the Stylefunction along with the layer declaration and then call it by declaring the properties.

In our case, we want a marker image that we have stored locally to represent the points on the map. Hence first of all, we define a variable image, that holds all the attributes to style the marker.

var image = new Icon({
  scale: 0.7,
  rotateWithView: false,
  anchor: [0.5, 1],
  anchorXUnits: 'fraction',
  anchorYUnits: 'fraction', 
 opacity: 1, 
 src: './marker.png'
});

Here, image is an object of the Icon class with the propertied defined. The file marker.png is stored locally on the same level as our javascript file. Next, we will define a styles variable that will contain the attributes we defined above.

var styles = { 
 'Point': new Style({  
  image: image 
 }), 
};

Once, this is done, all that is left is to call the StyleFunction, passing the style variable, we created above, as a parameter. This can be d

...
source: new VectorSource({  
    url: url,      
 format: new GeoJSON()   
 }), 
 style: styleFunction
  }))
...

Generating Overlays(Popups) from GeoJSON files

edit

Overlays are objects on the map tied to latitude/longitude coordinates, which show additional information about the point being marked. They move when we drag or zoom into the map. These overlays can be viewed in a variety of way. They could be displayed as labels for points of interest, or can be made to appear as popups so that when the user clicks on the point, they expand, and show information such as title, description, images etc. depending on what is available.

Generating the Popups

edit

To generate popups that show additional information, we first need to define an overlay as a container layer for our popups. Remember, we first need to import the Overlays module from Openlayers in our JS file, to make it work. Importing the module using

import Overlay from 'ol/Overlay';

Now, as mentioned earlier, let’s define our container layer for the Overlay,

var overlay = new Overlay({ 
   element: container, 
   autoPan: true,  
  offset: [0, -10]
});
map.addOverlay(overlay);


Constructing the Popups

edit

The next step is to style and display the popups that will trigger on a singleclick. To anchor the popups, we need separate div’s defined in our HTML file that will have a CSS id, using which we can style the popups. So, in our HTML file, we add the following lines for the div containers:

<div id="popup" class="ol-popup">  
    <a href="#" id="popup-closer" class="ol-popup-closer"></a> 
    <div id="popup-content">  </div>  
</div>

These three HTML ‘divs’ with id popup, popup-closer, popup-content will hold the popup. The div with id popup-content will hold the entire contents of the popup. The div with an ID of popup-closer defines the attributes of the popup when it will be closed. Now we have to define the properties for these HTML elements. The revelant CSS file is given here .Now, let us quickly bring these elements into our Javascript file so that we can control the contents of the popups. This can be done by

var   
   container = document.getElementById('popup'), 
   content_element = document.getElementById('popup-content'), 
   closer = document.getElementById('popup-closer');  
   //click handler to hide the popup
  closer.onclick = function() {    
  overlay.setPosition(undefined); 
  closer.blur();    
  return false;
};

Extracting Wikidata generated information from our GeoJSON file

edit

Now comes the part to extract the information from the GeoJSON file. Let’s create an action for clicking the points first.

map.on('singleclick', function(evt){  
  var feature =    map.forEachFeatureAtPixel(evt.pixel,
  function(feature, layer) {   
     return feature;  
 });

Lets go over this one more time. ‘map’ is the variable that holds our entire map. So first, on the event of a ‘single click’, we trigger a callback function that calls another method forEachFeatureAtPixel, which is an inbuilt-method of OpenLayers that detects features intersecting at that pixel on the viewport and returns the response to the ‘feature’ variable. We then return the feature variable for further use. Now comes the last and the most fun part of this exercise. We check if a feature exists at that point, determined by the feature variable returned earlier,and then if it exists, we retrieve the information from the GeoJSON file, and display it using innerHTML on the viewport. Here is the code for the same,

if (feature) {  
var geometry = feature.getGeometry(); 
var coord = geometry.getCoordinates();  
console.log(imageurl); 
var content = '<h3>' +  feature.get('placeLabel') + '</h3>'; 
content += '<img src = ' + imageurl+ '>';
content += '<h5>' + feature.get('location') + '</h5>';                content_element.innerHTML = content;        overlay.setPosition(coord);                console.info(feature.getProperties());
}});

Here, we are extract placeLabel and location coordinates returned by the GeoJSON file and display as H1 and H3 text inside the popup.

Putting images into Popups

edit

If our GeoJSON files contain image links available through Wikimedia, we can simply extract the image property from our GeoJSON file, and display into the viewport the same way as we did the other text pieces.

var imageurl = feature.get('image');
content += '<img src = ' + imageurl+ '>';

This way we have the Title, image( if available), and then other description inside our Popups.

All the code snippets mentioned here, can be found at : https://github.com/siriuswapnil/maps/blob/7.2-devel-osm-working/osm-source/viewer/main.js#L758

Conclusion

edit

Here we say how we can style the markers available through the GeoJSON files and then show an overlay containing revelant information, again, extracted from the GeoJSON file. Our next step will be to modify the markers for different types of points. Also, it would be great to include more specialized information inside the popups that will enhance the user experience even more.