-2

I have basic google maps with a bunch of polygons spread throughout the map. I want to be able to navigate to those polygons based on the id given in the text box below the map.

My question: If I enter a number in the box, and hit submit, how do I tell google maps too look for that polygon and center to it?

#html

<h1>Hex Map</h1>
<div id="map_wrapper">
    <div id="map"></div>
</div>
<form>
 <label for="poly">First name:</label>
  <input type="text" id="poly" name="poly"><br><be>
 <input type="submit" value="Submit">
</form>

JS

let map;
var infowindow = null;

function initMap() {

    map = new google.maps.Map(document.getElementById("map"), {
        center: {lat: 30.1572523, lng: -92.0299477},
        zoom: 3,
    });

    google.maps.event.addListenerOnce(map, 'bounds_changed', function () {
        //alert(map.getBounds().getNorthEast().lat());
    });

    map.data.loadGeoJson(
      "hexmap.geojson"
    );

    google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
        document.getElementById('map').style.opacity = 1;
    })
    map.data.setStyle({
        fillColor: 'green',
        strokeWeight: 1
    })

    // map.data.addListener('mouseover', function(event) {
    //     console.log(event.feature.getProperty('_uid1_'))
    //     document.getElementById('mapinfo').innerHTML = event.feature.getProperty('_uid1_');
    // })

    const constentString = 'hex + '

    map.data.addListener('click', function(event) {
        message = 'hex id: ' + event.feature.getProperty('_uid1_');
        infowindow && infowindow.close();
        infowindow = new google.maps.InfoWindow();
        infowindow.setContent(message);
        infowindow.setPosition(event.latLng);
        infowindow.open(map);

    })


}
//"https://drive.google.com/file/d/1v-VZtbbz4H2KiMvkRcc7nL_6JKQqlHwM/view?usp=sharing'"
geocodezip
  • 158,664
  • 13
  • 220
  • 245
arcee123
  • 101
  • 9
  • 41
  • 118
  • Please provide a [mcve] that demonstrates your issue, including a sample of the data required. – geocodezip Mar 14 '22 at 20:52
  • I can't do that, because the google-maps API requires my API key, and I can't give that oout. – arcee123 Mar 14 '22 at 21:07
  • Create the example, test it with your key, redact your key before posting it (I have keys I can use, and there are Google test keys that work in StackSnippets, if you are up to looking for them). Adding sample GeoJSON to your question would be helpful in any case. – geocodezip Mar 14 '22 at 22:55
  • Related question: [zoom to geojson polygons bounds in Google Maps API v3](https://stackoverflow.com/questions/28507044/zoom-to-geojson-polygons-bounds-in-google-maps-api-v3) – geocodezip Mar 15 '22 at 00:02
  • https://jsfiddle.net/8cvhwdgr/1/ – arcee123 Mar 15 '22 at 05:02
  • the expectation is that I get a ID from external means (e.g. a form entry) and zoom to that polygon associated. Unfortuantely, I'm at a loss in understanding how to tell the map to look for a specific polygon based on that ID, and not on a click. – arcee123 Mar 16 '22 at 15:58
  • FYI, your "ID", is not the feature ID, it is an arbitrary property of the feature. (it would be simpler if it was the featureID) – geocodezip Mar 16 '22 at 16:38
  • right now, my "ID" is a surrogate key value in the GEOJSON. I need to find the geojson based on that field. – arcee123 Mar 16 '22 at 17:36

1 Answers1

1
  1. to zoom to a polygon, use the function that does that from this related question: zoom to geojson polygons bounds in Google Maps API v3:
// zoom to the feature
var bounds = new google.maps.LatLngBounds();
processPoints(e.feature.getGeometry(), bounds.extend, bounds);
map.fitBounds(bounds);

function processPoints(geometry, callback, thisArg) {
  if (geometry instanceof google.maps.LatLng) {
    callback.call(thisArg, geometry);
  } else if (geometry instanceof google.maps.Data.Point) {
    callback.call(thisArg, geometry.get());
  } else {
    geometry.getArray().forEach(function(g) {
      processPoints(g, callback, thisArg);
    });
  }
}
  1. To use that to zoom to the polygon that has the matching value of the _uid1_ property, you can use Data.forEach, checking to see if the desired property matches, then if a match is found, zoom to that feature:
var uid1 = ($("#coords input[name=coord]").val());
var feature = map.data.forEach(function(feature) {
  if (feature.getProperty("_uid1_")==uid1) {
     var bounds = new google.maps.LatLngBounds();
     processPoints(feature.getGeometry(), bounds.extend, bounds);
     map.fitBounds(bounds);
  }
})
  1. You have an issue with your "submit" button, that will submit the page to the server, which in this case, refreshes the page and reloads the map. Related question: Stop form refreshing page on submit

live example

screenshot zoomed to polygon

code snippet:

let map;
let inputGeoJson;
var infowindow = null;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: 30.1572523,
      lng: -92.0299477
    },
    zoom: 3,
  });

  map.data.addGeoJson(geoJson);

  google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
    document.getElementById('map').style.opacity = 1;
  })
  map.data.setStyle({
    fillColor: 'green',
    strokeWeight: 1
  })

  map.data.addListener('click', function(event) {
    message = 'hex id: ' + event.feature.getProperty('_uid1_');
    infowindow && infowindow.close();
    infowindow = new google.maps.InfoWindow();
    infowindow.setContent(message);
    infowindow.setPosition(event.latLng);
    infowindow.open(map);

  })
  // zoom to the clicked feature
  map.data.addListener('click', function(e) {
    var bounds = new google.maps.LatLngBounds();
    processPoints(e.feature.getGeometry(), bounds.extend, bounds);
    map.fitBounds(bounds);
  });
}

function processPoints(geometry, callback, thisArg) {
  if (geometry instanceof google.maps.LatLng) {
    callback.call(thisArg, geometry);
  } else if (geometry instanceof google.maps.Data.Point) {
    callback.call(thisArg, geometry.get());
  } else {
    geometry.getArray().forEach(function(g) {
      processPoints(g, callback, thisArg);
    });
  }
}
$(document).ready(function() {
  $(document).on('click', '#coords', function() {
    // do your things
    document.getElementById('map').style.opacity = 0;
    console.log($("#coords input[name=coord]").val());
    document.getElementById('map').style.opacity = 1;
    var uid1 = ($("#coords input[name=coord]").val());
    var feature = map.data.forEach(function(feature) {
      if (feature.getProperty("_uid1_") == uid1) {
        var bounds = new google.maps.LatLngBounds();
        processPoints(feature.getGeometry(), bounds.extend, bounds);
        map.fitBounds(bounds);
      }
    })
    return false;
  });
});

var geoJson = {
  "type": "FeatureCollection",
  "name": "hexmap",
  "crs": {
    "type": "name",
    "properties": {
      "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
    }
  },
  "features": [{
      "type": "Feature",
      "properties": {
        "_uid1_": 7485,
        "_uid0_": 7485,
        "id": 155,
        "country": "United States"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-68.5, 45.899346400575254],
            [-68.0, 45.033320996790813],
            [-67.0, 45.033320996790813],
            [-66.5, 45.899346400575254],
            [-67.0, 46.765371804359688],
            [-68.0, 46.765371804359688],
            [-68.5, 45.899346400575254]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_uid1_": 7486,
        "_uid0_": 7486,
        "id": 155,
        "country": "United States"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [-68.5, 47.631397208144129],
            [-68.0, 46.765371804359688],
            [-67.0, 46.765371804359688],
            [-66.5, 47.631397208144129],
            [-67.0, 48.49742261192857],
            [-68.0, 48.49742261192857],
            [-68.5, 47.631397208144129]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_uid1_": 7487,
        "_uid0_": 7487,
        "id": 155,
        "country": "United States"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [171.5, 52.827549630850761],
            [172.0, 51.96152422706632],
            [173.0, 51.96152422706632],
            [173.5, 52.827549630850761],
            [173.0, 53.693575034635202],
            [172.0, 53.693575034635202],
            [171.5, 52.827549630850761]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "_uid1_": 7488,
        "_uid0_": 7488,
        "id": 155,
        "country": "United States"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [173.0, 51.96152422706632],
            [173.5, 51.095498823281886],
            [174.5, 51.095498823281886],
            [175.0, 51.96152422706632],
            [174.5, 52.827549630850761],
            [173.5, 52.827549630850761],
            [173.0, 51.96152422706632]
          ]
        ]
      }
    },
{ "type": "Feature", "properties": { "_uid1_": 7489, "_uid0_": 7489, "id": 155, "country": "United States" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 176.0, 51.96152422706632 ], [ 176.5, 51.095498823281886 ], [ 177.5, 51.095498823281886 ], [ 178.0, 51.96152422706632 ], [ 177.5, 52.827549630850761 ], [ 176.5, 52.827549630850761 ], [ 176.0, 51.96152422706632 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7490, "_uid0_": 7490, "id": 155, "country": "United States" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 177.5, 51.095498823281886 ], [ 178.0, 50.229473419497445 ], [ 179.0, 50.229473419497445 ], [ 179.5, 51.095498823281886 ], [ 179.0, 51.96152422706632 ], [ 178.0, 51.96152422706632 ], [ 177.5, 51.095498823281886 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7491, "_uid0_": 7491, "id": 155, "country": "United States" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 177.5, 52.827549630850761 ], [ 178.0, 51.96152422706632 ], [ 179.0, 51.96152422706632 ], [ 179.5, 52.827549630850761 ], [ 179.0, 53.693575034635202 ], [ 178.0, 53.693575034635202 ], [ 177.5, 52.827549630850761 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7492, "_uid0_": 7492, "id": 155, "country": "United States" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 179.0, 51.96152422706632 ], [ 179.5, 51.095498823281886 ], [ 180.5, 51.095498823281886 ], [ 181.0, 51.96152422706632 ], [ 180.5, 52.827549630850761 ], [ 179.5, 52.827549630850761 ], [ 179.0, 51.96152422706632 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7493, "_uid0_": 7493, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -5.5, 47.631397208144129 ], [ -5.0, 46.765371804359688 ], [ -4.0, 46.765371804359688 ], [ -3.5, 47.631397208144129 ], [ -4.0, 48.49742261192857 ], [ -5.0, 48.49742261192857 ], [ -5.5, 47.631397208144129 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7494, "_uid0_": 7494, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -5.5, 49.363448015713004 ], [ -5.0, 48.49742261192857 ], [ -4.0, 48.49742261192857 ], [ -3.5, 49.363448015713004 ], [ -4.0, 50.229473419497445 ], [ -5.0, 50.229473419497445 ], [ -5.5, 49.363448015713004 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7495, "_uid0_": 7495, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -4.0, 46.765371804359688 ], [ -3.5, 45.899346400575254 ], [ -2.5, 45.899346400575254 ], [ -2.0, 46.765371804359688 ], [ -2.5, 47.631397208144129 ], [ -3.5, 47.631397208144129 ], [ -4.0, 46.765371804359688 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7496, "_uid0_": 7496, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -4.0, 48.49742261192857 ], [ -3.5, 47.631397208144129 ], [ -2.5, 47.631397208144129 ], [ -2.0, 48.49742261192857 ], [ -2.5, 49.363448015713004 ], [ -3.5, 49.363448015713004 ], [ -4.0, 48.49742261192857 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7497, "_uid0_": 7497, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.5, 42.435244785437497 ], [ -2.0, 41.569219381653056 ], [ -1.0, 41.569219381653056 ], [ -0.5, 42.435244785437497 ], [ -1.0, 43.301270189221938 ], [ -2.0, 43.301270189221938 ], [ -2.5, 42.435244785437497 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7498, "_uid0_": 7498, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.5, 44.167295593006372 ], [ -2.0, 43.301270189221938 ], [ -1.0, 43.301270189221938 ], [ -0.5, 44.167295593006372 ], [ -1.0, 45.033320996790813 ], [ -2.0, 45.033320996790813 ], [ -2.5, 44.167295593006372 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7499, "_uid0_": 7499, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.5, 45.899346400575254 ], [ -2.0, 45.033320996790813 ], [ -1.0, 45.033320996790813 ], [ -0.5, 45.899346400575254 ], [ -1.0, 46.765371804359688 ], [ -2.0, 46.765371804359688 ], [ -2.5, 45.899346400575254 ] ] ] } },
{ "type": "Feature", "properties": { "_uid1_": 7500, "_uid0_": 7500, "id": 156, "country": "France" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -2.5, 47.631397208144129 ], [ -2.0, 46.765371804359688 ], [ -1.0, 46.765371804359688 ], [ -0.5, 47.631397208144129 ], [ -1.0, 48.49742261192857 ], [ -2.0, 48.49742261192857 ], [ -2.5, 47.631397208144129 ] ] ] } },

  ]
}
html,
body {
  height: 100%;
  ;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#map {
  height: 100%;
  ;
  width: 100%;
  margin: 0px;
  padding: 0px;
}

#map_wrapper {
  background: url(https://ressio.github.io/lazy-load-xt/dist/loading.gif) center center no-repeat;
  height: 90%;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Test Google Maps</title>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="robots" content="noindex, nofollow">
  <meta name="googlebot" content="noindex, nofollow">
  <meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>
  <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDtOvrOsi7BWG_X0ezrH7316lNV8mpVDEQ&callback=initMap&v=weekly" async></script>
  <div id="map_wrapper">
    <div id="map"></div>
  </div>
  <form id="coords" action="">
    <input name="coord" value="7486" />
    <input type="button" value="submit" />
  </form>

</body>

</html>
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • Thank you so much. This got me exactly where I needed to go. The only frustration I can see in the code is that for each time we want to do this particular opreation, the Map.data.forEach obligates me to cycle through all the objects every time. Otherwise, thank you again. This was brilliant. – arcee123 Mar 20 '22 at 06:17
  • This is a proof of concept. You can cache the bounds in a "map" or array by your "id" when the GeoJSON is loaded, and use that instead. Means more processing up front though. – geocodezip Mar 20 '22 at 13:03
  • Another option would be to modify your GeoJSON to make the ID the value you want to search for, and use `getFeatureByID`. – geocodezip Mar 20 '22 at 13:31