GMapsable: usage

0
55

Have you ever needed to place some sort of geographic data on a map? For example, on my job I develop analytical web services and I had to display orders grouped by latitude and longitude. And not a static table, but dynamic one, which changes its detailisation with the map zoom!

Unfortunately, I found no existing solution for this task. Google Maps allow to add markers and shapes to the map, but this is not appropriate, too few information is showed. However, Google Maps allow to create custom overlays. Thus, I created GMapsTable for encapsulating this stuff. A live example is here.

So, what do we have? A server with a database, that processes and sends data in JSON; and a client with JavaScript, that sends queries and handles the results putting the data on Google Maps.

The data has accumulative nature (in my case, each region may have: orders count, clients count, and mean sum of orders). The data can and must be presented with different detailisation for different map scales. And this is done on server-side only, client does not change the data.

Here is the main content of an HTML page for GMapsTable:

 ..in <head>:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY"></script>
<script src="http://www.aivanf.com/static/gmt/gmapstable.js"></script>

 ..in <body>:
<div id="map"></div>

GMapsTable allows you to abstract from direct interaction with GoogleMaps API. All you just need is to provide an appropriate data object. Time to dive into JavaScript! To use GMapsTable you need to obtain a DataContainer object for you map’s div element:




var container = new DataContainer("map", {
 zoom: 9,
 center: {lat: 55.7558, lng: 37.6173},
 mapTypeId: 'roadmap'
});

Then you have to specify two functions:

container.dataLoader = function (scale, borders) {
 ... call container.processData(some_data)
}

container.scaler = function getScale(zoom) {
 ... return some number
}


But what to write inside?.. Let’s begin with how GMapsTable works.

DataContainer handles your data visualisation process and worries if it must be updated. At the start and when zoom or bounds are changed significantly, it calls dataLoader function. There you should generate a data object and pass it to DataContainer.processData function. It’s structure is as follows:

data: {
 minLat: float,
 difLat: float,
 minLon: float,
 difLon: float,
 scale: int,
 table: [
 [value, value, ...],
 [value, value, ...],
 ...
 ],
 tocache: boolean
}

A value can be a number, a string or other object if you specify custom cell formatter. Scale is an number of parts in each lat/lon unit. The “tocache” property says if the values for this scale should be saved and no longer requested. To clarify, have a look on an example:

data: {
 minLat: 55.0,
 difLat: 2.0,
 minLon: 37.0,
 difLon: 1.0,
 scale: 2,
 table: [
 [1, 3, 0, 1],
 [0, 1, 2, 0]
 ],
 tocache: true
}

Here the data covers region from 55.0, 37.0 to 57.0, 38.0 and splits every lat/lon into two parts. Also the values will be saved for this scale value.

The zoom is the variable of Google Maps API, ranged between 1 (world map) and 22 (street view). It’s expensive and helpless to request and store values for every zoom value, so, GMapsTable translates it to scale value — number of parts to divide latitude and longitude units.

To provide flexible and immediate table display, GMapsTable can store datasets for some scales. For example, I had a table on my database with coordinates from all the Russia — about 42 thousand cells for scale 10 (500 KB, can be easily stored and processed on a desktop browser) and 17 million for scale 200 (several MB, causes significant freezing). Hereby, the server estimates cells count and to certain extent starts cutting the data. The algorithm:

The bounds argument is a JavaScript object with properties minlat, maxlat, minlon, maxlon — current bounds of Google Maps view with big padding on each side.

In your dataLoader realisation you can ignore arguments if you don’t need scaling the detailisation or if your data does not cover huge region — just indicate preferred min/max/lat/lon and scale in your data response. But I suggest the full behaviour of dataLoader:

You can find full and well-commented example of GMapsTable usage here:

http://www.aivanf.com/static/gmt/example.html
http://www.aivanf.com/static/gmt/example.js

Or on GitHub:

https://github.com/AivanF/GMapsTable

SaveSaveSave

LEAVE A REPLY