Reputation: 23
I am referencing a geoJson file in the following location to add state polygons to a map of India
https://raw.githubusercontent.com/geohacker/india/master/state/india_telengana.geojson
The map is using the googlemaps api
What I would like to do now is make each polygon a clickable event.
In researching I've found that:
I have now created a JSFiddle but I can't get the final map to load (It loads outside of fiddle):
https://jsfiddle.net/everare/df6jbuft/
The code here shows my attempting to invoke an event using guidance from googlemaps https://developers.google.com/maps/documentation/javascript/combining-data
HTML:
<div class="container">
<div id="map"style="width:700px;height:700px;border:10px solid black;"> </div>
</div>
Javascript:
//Map construction
var map;
function initMap() {{
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 22.71, lng: 82.48},
zoom: 5,
zoomControl: true,
zoomControlOptions: {
position: google.maps.ControlPosition.TOP_LEFT
},
styles:[
{ elementType: 'geometry', stylers: [ {color: '#242f3e'}]},
{ elementType: 'labels.text.fill', stylers: [{color: '#746855'}]},
{ elementType: 'labels.text.stroke', stylers: [{color: '#242f3e'}]},
{ featureType: 'administrative', elementType: 'geometry', stylers: [{visibility: 'off'}]},
{ featureType: 'administrative.locality',elementType: 'labels.text.fill',stylers: [{color: '#d59563'}]},
{ featureType: 'poi', stylers: [{visibility: 'off'}]},
{ featureType: 'poi', elementType: 'labels.text.fill',stylers: [{color: '#d59563'}]},
{ featureType: 'poi.park', elementType: 'geometry', stylers: [{color: '#263c3f'}] },
{ featureType: 'poi.park', elementType: 'labels.text.fill', stylers: [{color: '#6b9a76'}]},
{ featureType: 'road', stylers: [{visibility: 'off'}]},
{ featureType: 'road', elementType: 'geometry', stylers: [{color: '#38414e'}]},
{ featureType: 'road', elementType: 'geometry.stroke', stylers: [{color: '#212a37'}]},
{ featureType: 'road', elementType: 'labels.icon', stylers: [{visibility: 'off'}]},
{ featureType: 'road', elementType: 'labels.text.fill', stylers: [{color: '#9ca5b3'}]},
{ featureType: 'road.highway', elementType: 'geometry', stylers: [{color: '#746855'}]},
{ featureType: 'road.highway', elementType: 'geometry.stroke',stylers: [{color: '#1f2835'}]},
{ featureType: 'road.highway', elementType: 'labels.text.fill', stylers: [{color: '#f3d19c'}]},
{ featureType: 'transit', stylers: [{visibility: 'off'}]},
{ featureType: 'transit', elementType: 'geometry', stylers: [{color: '#2f3948'}]},
{ featureType: 'transit.station', elementType: 'labels.text.fill', stylers: [{color: '#d59563'}]},
{ featureType: 'water', elementType: 'geometry',stylers: [{color: '#17263c'}]},
{ featureType: 'water', elementType: 'labels.text.fill', stylers: [{color: '#515c6d' }]},
{ featureType: 'water', elementType: 'labels.text.stroke', stylers: [{color: '#17263c'}]
}
]
});
}
// Loads the state boundary polygons from a GeoJSON source.
function loadMapShapes() {
map.data.loadGeoJson('https://raw.githubusercontent.com/geohacker/india/master/state/india_telengana.geojson', { idPropertyName: 'STATE' });
}
//Responds to the mouse-in event on a map shape (state).
//@param {?google.maps.MouseEvent} e
function mouseInToRegion(e) {
// set the hover state so the setStyle function can change the border
e.feature.setProperty('state', 'hover');
}
//Polygon style
map.data.setStyle({
fillColor: '#FF8000',
strokeWeight: 1
});
// set up events for google.maps.Data
map.data.addListener('mouseover', mouseInToRegion);
// state polygons only need to be loaded once, do them now
loadMapShapes();
}
CSS:
body {
background-color: white;
background-repeat: no-repeat;
background-position: 0px 0px;
}
.container {
position: absolute;
top: 100px;
left: 60px;
Upvotes: 1
Views: 1374
Reputation: 1170
If your map.data.loadGeoJson
results in a properly-formatted data object, then the data
for map
should already be set. I would console.log
the data to ensure that the object being produced is what you think it is.
I'm not sure if this is 'canonical' workflow, but my workflow goes as follows:
So my code for a map with one data layer would look like this:
// Step 1. Define Map Options
// note centroid_lat and centroid_lng are evaluated from the data, elsewhere
var tango = {lat: centroid_lat, lng: centroid_lng};
var mapOptions = {
zoom: 15,
center: tango,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Step 2. Make a new Map object
var map=new google.maps.Map($('#mapcanvas')[0], mapOptions);
// Step 3. Make a new Data Layer object
var cLayer = new google.maps.Data();
// Step 4. Put some data into the layer
$.getJSON("json/myfile.json", function(data){
d1 = topojson.feature(data, data.objects.address)
cLayer.addGeoJson(d1);
});
// Step 5. Assign the new layer to the map
cLayer.setMap(map);
The $.getJSON
and topojson
should make it clear that this example uses jquery
and the d3js
topojson
library.
Most of the layers I create actually retrieve their data from a PostGIS-enabled PostgreSQL database using a PHP script that gets fed some filtering inputs, vets the inputs (to prevent SQL injection etc), then fills in variable names in a query which is passed to PostgreSQL. The query produces GeoJSON and pipes it back to the DOM, where it is attached to the data object.
So my code to populate the data layer would be
// db_schema, base_table and thisBox are set elsewhere (thisBox is the
// bounding box of the viewport)
var c_url="v1/ws_base_fetch.php?schema="+db_schema+"&table="+base_table+"&thisBox="+thisBox;
// console.log('URL is :'+c_url); // testing only
$.getJSON(
c_url,
null,
function success(data) {
// Add data to layer, specifying address as idPropertyName
// this makes address unique, and data with duplicate address
// will not be loaded (it will be retrieved though)
cLayer.addGeoJson(data,{idPropertyName:"address"});
});
Upvotes: 1