ElaineE
ElaineE

Reputation: 23

How to make multiple geoJson polygons into multiple clickable events

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

Answers (1)

GT.
GT.

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:

  • Define the map options;
  • Create a new map;
  • define layers (in your case there would only be 1);
  • load data into the layers;
  • associate the layers to a map.

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

Related Questions