Some maps are packaged with jquery mapael and some other are available on the mapael-maps repository (feel free to contribute to this repository !). In this tutorial, I will explain you how to create a new map for jQuery Mapael from an existing SVG file. Let’s create a United Kingdom map for mapael !
The first step is to find an SVG map file. You can find many maps on SVG format with a Creative Commons license on the web. You can find this kind of resources on Natural Earth Data or Wikimedia Commons. A map is based on a specific projection such as mercator, Miller, Lambert or equirectangular projection. Here is a list of map projections.
If you want to plot cities by latitude and longitude on your map, you have to care about the projection that is used on the choosen map. Indeed, the algorithm to convert a latitude and a longitude to x and y coordinates depends on the map projection. The simpliest projection is the equirectangular one (see below fore more information). https://commons.wikimedia.org/wiki/Main_Page
Here is the map of of United kingdom with an equirectangular projection and under SVG format.
Inkscape is a powerful Open Source tool to edit vector graphics. It will allows us to clean the map by removing unwanted SVG paths and groups, SVG transformations, and trimming the map. Thus, we will be able to extract only the wanted paths that compose the map.
Go to File > Inkscape Preferences > Transforms. Ensure that “Optimized“ is checked for the “Store transformation” option. It will force Inkscape to translate SVG transforms (such as translations, rotations, …) into coordinates within the paths.
All we want to retrieve from the SVG file are the paths of each county that will compose our map. We do not want lakes, rivers, small islands, neighbourhood countries. You can remove all these unwanted elements.
The paths may be grouped within SVG <g> elements. As transformations can be applied to SVG groups, we have to ungroup all groups from the SVG file. Ungroup all objects will make inkscape translate transforms into coordinates within the paths. In order to ungroup all groups, open the XML editor (edit > XML editor) and, for each <g> element found in the XML tree, click on Object > Ungroup.
Ungroup all groups through the XML editor
Cleaned map
Once your SVG file is cleaned from all unwanted elements and all groups are ungrouped, you can be in front of two cases :
First case : the SVG file contains paths that already represent correctly the different areas of the country. In such a case, you just have to select all the wanted areas (by holding CTRL + uppercase pressed) and copy them in a new Inkscape document.
Second case : The SVG file contains paths that do not match with the areas (for example, the file can contains paths just for the boundaries). In such a case, you can use the "Fill bounded areas" tool : . Set appropriate values for the “Threshold” option (you can set it to 0 if the concerned area has a single color) and the "grow/shrink" option. Ensure that you have zoomed your map enough before filling the areas. Indeed, the filling precision depends on the zoom level. You can now fill all the wanted areas. If you can't fill an area with only one click because of the zoom level, you can complete the filling by clicking on another area and holding CTRL + Uppercase pressed. When all the wanted areas are filled, you can select them (by holding CTRL + Uppercase pressed) and copy them in a new Inkscape document.
All the wanted areas are selected in order to copy them in a new document
The areas in the new document may not fit with the document dimensions. In this case, go to File > Document Properties > Resize page to content, and click on the “Resize page to drawing or selection”. Resize the document makes Inkscape group the areas in a <g> element and apply the transformation on this element. In order to translate this transformation into the paths coordinates, open the XML editor (edit > XML editor) and, for each <g> element found in the XML tree, click on Object > Ungroup.
Resized page to drawing
The last step is to associate more explicit IDs than “pathXXX” to each area. To achieve this, you can use the XML editor.
Associate more explicit IDs to the paths
Save this new SVG file, we are done with Inkscape but you may want to go further by reading the next part.
I will not explain all the features for editing vector images provided by Inkscape because this is not a tutorial dedicated to the tool, but some of them are very usefull for refining the maps.
If your final javascript map is too big, you can lighten the paths data with Inkscape by using the tool “Path > Simplify”. If your map is not enough lightened, you can also change the value of the round precision field in the tool “SVG To mapael” (see below).
Sometimes, a single area is divided into several distinct SVG paths. Inkscape allows you to gather these paths in one single path : select all paths to be combined (by holding Uppercase) and use the tool “Path > Combine”.
In some other cases, you may want to break apart areas that are gathered in one single SVG path. This is the aim of the tool “Path > Break apart”.
You have two ways for building the basic JSON map file for Mapael.
The tedious way : as SVG is just XML, you can open the file with any text editor. You just have to extract manually the wanted paths data (‘d’ attribute in
(function($) { $.extend(true, $.fn.mapael, { maps :{ yourMapName : { width : 600, height : 500, getCoords : function (lat, lon) { // Convert latitude,longitude to x,y here return {'x' : lat, 'y' : lon}; } elems : { // List of SVG paths for building the map "department-29" : "m 37.28,156.11 c -1.42,1.23 -3.84,1.18 (...)", "department-22" : "m 77.67,146.73 c -2.58,0.94 -4.37,2.6 -5.78,4.84 1.21 (...)", (...) } } } } ); })(jQuery);
The easy way : Go to the "SVG to Mapael" tool and submit your brand new SVG file in order to get the JS file generated for Mapael. You can set a value for the round precision field in order to round all paths coordinates. It allows to lighten the size of the output. Usually, a round precision of 2 is enough in most of cases. Leave this input blank if you do not want to round the paths coordinates.
Save the output in a javascript and your map should now be ready to be loaded into jQuery Mapael !
The UK map displayed through jQuery mapael
If you want to go further with your map, you may want plot cities by latitude and longitude on it. We assume that the projection of your map is an equirectangular one.
With this projection, the algorithm to convert a latitude and a longitude to x and y coordinates is as simple as that :
You just have to found the proper values for xFactor, yFactor, xOffset and yoffset in order to be able to plot cities by latitude and longitude on your map.
To get the values of xFactor and xOffset, you just have to resolve an equation with two unknowns. Plot two points at the max left and the max right of your map with x and y coordinates. Go to Google Map in order to find the matching longitudes for these two points (Right click > More info about this place on Google map) .
You can now find the values for xFactor and xOffset by resolving this equation (this is the tedious way, there is a tool for that, see below ;-) ) :
Then, you have to do exactly the same thing to get the values of yFactor and yOffset with matching latitudes.
You can use the getCoords() generator tool that will resolve equations and generate the getCoords() method for you !
Use mapael for plotting points in order s to find min x, max x, min y and max y coordinates. Here is an example for the United Kingdom map where I plotted four points with x and y coordinates on the map :
(function($) { $(function(){ $(".container1").mapael({ map : { name : "united_kingdom", zoom: { enabled:true }, defaultPlot : { size:5, attrs: { fill:"red", stroke:"white", "stroke-width":2, opacity:0.5 } } }, plots : { p1 : { x:647, y:3 }, p2 : { x:352, y:1238 }, p3 : { x:1, y:995 }, p4 : { x:818, y:945 } } }); });
Then, you can use Google Maps in order to find the matching latitudes and longitudes and fill the form of the getCoords() generator.
With the getCoords() function added to your JS vector map, you can now plot cities by latitude and longitude, here is an example with London plotted on the UK map (latitude : 51.5085300, longitude : -0.1257400) :
Your map for mapael is now complete ! Take a look at the mapael documentation to see what you can do with it. Feel free to contribute to mapael-maps repository (https://github.com/neveldo/mapael-maps) by adding your new map !