How to display polygon with Google Maps API? - json

My Problem:
I'm trying to create a data layer polygon with the Google Maps API using a geoJSON of county borders in Ireland. The data is from Ordance Survey Ireland so I'm pretty sure the problem I'm seeing is in my code somewhere.
Basically the code loops through the geoJSON file adding longitude and latitude points and drawing a line between them. When one county is done it adds the full outline to the map and moves to the next county. As you can see the outlines jump around the map at some points but some are perfectly drawn along the border of the county.
I have tried loading the geoJSON directly from the source URL as detailed in the API documentation and also played with the looping in my code but to no avail. Any help would be greatly appreciated.
Here is a link to the geoJSON I am using: Counties GEOJSON
<script>
let map;
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 7,
center: {
lat: 53.411080,
lng: -7.710753
},
mapTypeId: "roadmap",
});
let counties = httpGet('https://jameswalshe.ie/countiesGEOJSON.geojson');
counties = JSON.parse(counties);
for (let s = 0; s < counties['features'].length; s++) {
var countiesCoords = [];
var countyName = "county" + s;
for (let i = 0; i < counties['features'][s]['geometry']['coordinates'].length; i++) {
for (let y = 0; y < counties['features'][s]['geometry']['coordinates'][i].length; y++) {
for (let z = 0; z < counties['features'][s]['geometry']['coordinates'][i][y].length; z++) {
countiesCoords.push({
lat: counties['features'][s]['geometry']['coordinates'][i][y][z][1],
lng: counties['features'][s]['geometry']['coordinates'][i][y][z][0]
});
}
}
}
countyName = new google.maps.Polygon({
paths: countiesCoords,
strokeColor: "rgb(0, 139, 63)",
strokeOpacity: 1,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0,
});
countyName.setMap(map);
}
};
</script>

I used the map.data.loadGeoJson('data.json'); method instead of loading from another domain.

Related

Make polyline to show on google map horizontally and zoom it to center coordinate

I am using Google Maps API JavaScript. My use case is I need to plot coordinates (lat, lng) on maps (create markers) and join them through polyline. The co-ordinates will be very close to each other so when I try to plot them, they get hidden behind the first marker. So I find out the center and try to zoom so that all markers will be visible on the map.
I used bounds to find the center but I am not able to zoom it to center co-ordinate. I used map.fitBounds(latlng); It fits the coordinate on the screen.
But what I want to achieve is to make polyline (connecting all co-ordinate) always horizontal and zoom it to center co-ordinate.
enter code herevar bounds = new google.maps.LatLngBounds();
for (i = 0; i < temp.length; i++) {
bounds.extend(temp[i]);
}
var latlng = bounds.getCenter();
map.setCenter(latlng);
As the coordinate will always be different, The polyline will be in any direction, but I always want to show it horizontally on the map.
what I get :
enter image description here
what i want to acheive:
enter image description here
Any suggestion will be appreciated.
Thanks in Advance.
I achieve something like this by using the following:
Use computeHeading() function of Geometry library to get the angle from your first to your last coordinate on the line. Make sure to add &libraries=geometry to your Maps JS script tag.
Once you get the heading, you can use the map.setHeading() function to change the angle of your view and after some testings,I can see that you can achieve the horizontal view by subtracting it to 90 degrees.
Here's the sample code and code snippet below:
function initMap() {
const map = new google.maps.Map(document.getElementById("map"), {
center: {
lat: 40.756795,
lng: -73.954298
},
zoom: 16,
tilt: 47.5,
mapId: "90f87356969d889c",
});
//array of your points
const markerCoordinates = [
{ lat: 40.758481, lng: -73.958269 },
{ lat:40.754649, lng: -73.949563 },
];
//creating marker from your points
for (let i = 0; i < markerCoordinates.length; i++) {
const marker = markerCoordinates[i];
new google.maps.Marker({
position:marker,
map,
});
}
//creating polyline from your points
const createdPolyline = new google.maps.Polyline({
path: markerCoordinates,
geodesic: true,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
});
createdPolyline.setMap(map);
//get the heading(angle) of the first coordinate from the last coordinate
const heading = google.maps.geometry.spherical.computeHeading(
markerCoordinates[0],
markerCoordinates[1]
)
//once you get the heading subtract it by 90 to get a horizontal view
map.setHeading(heading-90)
}

Build polygon in google maps from this format

I'm trying to display polygons in google map. I have a .xlsx file with a column named "polygon" in which are polygon coordinates in a strange format.
For example: [[], [[-68.0913, -38.95585], [-68.09148, -38.95666], [-68.07378, -38.9591], [-68.0393, -38.96023], [-68.03909, -38.95884], [-68.03909, -38.95517], [-68.03273, -38.95452], [-68.03288, -38.95122], [-68.03322, -38.94787], [-68.04327, -38.94201], [-68.06786, -38.93913], [-68.07294, -38.94037], [-68.07719, -38.94237], [-68.07908, -38.94347], [-68.08127, -38.94434], [-68.08457, -38.94739], [-68.1084, -38.9478], [-68.10842, -38.95442], [-68.0914, -38.9549], [-68.09136, -38.95559], [-68.09123, -38.95594]], [[-68.11045, -38.95312]], [[-68.09643, -38.96523], [-68.0967, -38.95809], [-68.09688, -38.95342], [-68.07472, -38.95842], [-68.04073, -38.95897], [-68.03989, -38.95899], [-68.03897, -38.95901], [-68.0391, -38.96296], [-68.04457, -38.96303], [-68.04461, -38.96304], [-68.04488, -38.97065], [-68.04485, -38.97065], [-68.04489, -38.97132], [-68.05176, -38.97112], [-68.05704, -38.97265], [-68.05725, -38.97858], [-68.06837, -38.97866], [-68.06886, -38.97315], [-68.06901, -38.96554], [-68.07631, -38.96542]]].
Is it possible to build a polygon with this data structure or it's an incorrect format?
Your data is a GeoJSON like coordinates format.
To translate that into a Google Maps Polygon:
// go through the outer array (of polygons)
for (var i = 0; i < coords.length; i++) {
// array for the LatLng coordinates
var polygonCoords = [];
// go through each coordinate in the array.
// GeoJSON is [longitude,latitude]
for (var j = 0; j < coords[i].length; j++) {
var pt = new google.maps.LatLng(coords[i][j][1], coords[i][j][0])
polygonCoords.push(pt);
}
// Construct the polygon.
var polygon = new google.maps.Polygon({
paths: polygonCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map
});
}
}
proof of concept fiddle
code snippet:
// This example creates a simple polygon representing the Bermuda Triangle.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 5,
center: {
lat: 24.886,
lng: -70.268
},
mapTypeId: 'terrain'
});
var coords = [[], [[-68.0913, -38.95585], [-68.09148, -38.95666], [-68.07378, -38.9591], [-68.0393, -38.96023], [-68.03909, -38.95884], [-68.03909, -38.95517], [-68.03273, -38.95452], [-68.03288, -38.95122], [-68.03322, -38.94787], [-68.04327, -38.94201], [-68.06786, -38.93913], [-68.07294, -38.94037], [-68.07719, -38.94237], [-68.07908, -38.94347], [-68.08127, -38.94434], [-68.08457, -38.94739], [-68.1084, -38.9478], [-68.10842, -38.95442], [-68.0914, -38.9549], [-68.09136, -38.95559], [-68.09123, -38.95594]], [[-68.11045, -38.95312]], [[-68.09643, -38.96523], [-68.0967, -38.95809], [-68.09688, -38.95342], [-68.07472, -38.95842], [-68.04073, -38.95897], [-68.03989, -38.95899], [-68.03897, -38.95901], [-68.0391, -38.96296], [-68.04457, -38.96303], [-68.04461, -38.96304], [-68.04488, -38.97065], [-68.04485, -38.97065], [-68.04489, -38.97132], [-68.05176, -38.97112], [-68.05704, -38.97265], [-68.05725, -38.97858], [-68.06837, -38.97866], [-68.06886, -38.97315], [-68.06901, -38.96554], [-68.07631, -38.96542]]];
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < coords.length; i++) {
var polygonCoords = [];
for (var j = 0; j < coords[i].length; j++) {
var pt = new google.maps.LatLng(coords[i][j][1], coords[i][j][0])
bounds.extend(pt);
polygonCoords.push(pt);
}
// Construct the polygon.
var polygon = new google.maps.Polygon({
paths: polygonCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map
});
}
map.fitBounds(bounds);
}
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>

Google maps check if current bounds are inside the bounds of a data layer

I am loading a data layer in a google map, over a certain country (it's a drawing over a country):
map.data.addGeoJson(geoJsonObject);
I am pretty sure there isn't, but... is there a way to check that the bounds of the map are inside the bounds of the data layer?
(basically, I want to know, when the user navigates on the map, if the current viewport is inside data layer);
var bounds = this.map.getBounds();
var sw = bounds.getSouthWest();
Maybe I can query the data layer in the position of the south west bound and check for some props. indicating that I am inside that data layer?
Or at least:
Does anyone know a way how to get a certain feature object programmatically, knowing the lat and long?
Here the google maps uses events to get to the feature object:
map.data.addListener('click', function(event) {
event.feature.setProperty('isColorful', true);
});
But I do not want to use events. Is there a method to supply the coordinates of a point and get to the feature object?
Something like:
map.getFeature(lat, long).setProperty('isColorful', true);
google.maps.LatLngBounds.contains function could be utilized for that purpose, but since it accepts a single location, the following solution is suggested:
1) initialize data layer bounds from GeoJSON coordinates:
var dataLayer = map.data;
var layerBounds = new google.maps.LatLngBounds();
//1.collect all coordinates from data layer
dataLayer.forEach(function(f) {
var geometry = f.getGeometry();
processCoordinates(geometry, layerBounds.extend, layerBounds);
});
2) determine whether map bounds are within a layer bounds:
if (layerBounds.contains(map.getBounds().getNorthEast()) && layerBounds.contains(map.getBounds().getSouthWest())) {
//...
}
Working example
In the provided example green colored area will be displayed if map
bounds are within a layer bounds, and the red colored in
the opposite case:
var area;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 53.349248,
lng: -6.255323
},
zoom: 6,
mapTypeId: google.maps.MapTypeId.TERRAIN
});
displayDataLayer(map);
document.getElementById("btnShow").onclick = function() {
var result = displayDataLayerBoundsArea(map);
};
}
function displayDataLayer(map) {
var dataLayer = map.data;
dataLayer.loadGeoJson('https://gist.githubusercontent.com/vgrem/440708612b574764c309/raw/2a4e2feadc204806440c51a14c2ef1f54f4fc3d8/Census2011_Province_generalised20m.json');
dataLayer.setMap(map);
}
function displayDataLayerBoundsArea(map) {
var dataLayer = map.data;
var layerBounds = new google.maps.LatLngBounds();
//1.collect all coordinates from data layer
dataLayer.forEach(function(f) {
var geometry = f.getGeometry();
processCoordinates(geometry, layerBounds.extend, layerBounds);
});
if (area != null) {
area.setMap(null);
}
//2.determine whether map bounds are contained within a layer bounds
if (layerBounds.contains(map.getBounds().getNorthEast()) && layerBounds.contains(map.getBounds().getSouthWest())) {
//map.fitBounds(bounds);
area = new google.maps.Rectangle({
strokeColor: '#00FF00',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#00FF00',
fillOpacity: 0.35,
map: map,
bounds: {
north: layerBounds.getNorthEast().lat(),
south: layerBounds.getSouthWest().lat(),
east: layerBounds.getNorthEast().lng(),
west: layerBounds.getSouthWest().lng()
}
});
} else {
//map.fitBounds(bounds);
area = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
bounds: {
north: layerBounds.getNorthEast().lat(),
south: layerBounds.getSouthWest().lat(),
east: layerBounds.getNorthEast().lng(),
west: layerBounds.getSouthWest().lng()
}
});
}
}
function processCoordinates(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) {
processCoordinates(g, callback, thisArg);
});
}
}
#map {
width: 800px;
height: 640px;
}
<button id="btnShow">Show</button>
<div id="map"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
JSFiddle

Plot polyline in Google Maps

I'm exploring Google Maps Direction API and noticed I get an overview_polyline -> points result. I was able to enter that value in the "Encoded Polyline" field here: https://developers.google.com/maps/documentation/utilities/polylineutility. The result seems to be the actual driving directions from start location to end location. The data looks right to me.
I'd like to see this in a Google Map, but without all the map markers in between the start and end locations. How do I take this information and plot it on Google Maps?
From the Google Maps Javascript API Developers Guide: Geometry Library: Geometry Encoding
To decode an encoded path, simply call decodePath() passing the method the encoded string.
The caveat, is beware of backslash encoding (replace any occurrences in your encoded path string of "\\" with "\" if you have problems)
example fiddle
code snippet:
var map;
var bounds = new google.maps.LatLngBounds();
function initialize() {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(34, 108),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var jsonData = {
"overview_polyline": {
"points": "e`miGhmocNaN~DiBiNe#gEkEek#kNez#cJqq#sk#pGos#v]_}#aF_y#qm#qDe~#w]g~#gZ_Jo_#m_#yNsFgUpMov#~QebBrJq`BjTsx#w#kOqbEq_#qkCcf#}}Dej#yzCuf#o{Ba]m~EtVewAnBa`#sNmm#}dDufGqwA_|D_z#g~CmtBkuOrBmtCyG_yCam#{`Ee]qkB}d#ucDmDe|Aha#e}At]{v#xD}e#yf#aeIm^{rEgp#ahBiZu`BkVueH}gDwuXu`Fi__#yZecHgoAgyIl[ybCo^sgD_n#akBaJmeBog#yyAe`#ayB~FifCjNkmAzTwpAgf#cpFy~#{lJsg#ojHyi#e_Fq}#o`Dog#}tBoYmz#y`#sf#qf#ohCkLugBuv#seAg[ul#mMowBqc#iiC}eAcwCqm#_fBmuAypFyIiqA}BwyBy`#ogAwt#ypBezC{dIahBwxJgb#ytCw~AwvJkQwu#{t#yrCg{#s{Fgb#ehDzKsdAxO}vAiRmpCwcAorNuwAgdS_r#imJq[orAk]wrA_TyzAnFefAa\\guB_OmwAwF{tCwMcbDcr#m}_#}Qo_RgMo|A|d#kpAne#u{Brb#wnDzNkuB_D{v#eSgf#w\\ieAyb#guCii#ifCga#i_Amc#m]urAyoD}o#kiIsr#opQuLkhAc_#q`Bq\\}bEeEyi#iE}t#pHi|#tBmlBebB{qHq_BinFoWgpBoDuqEob#k{ConAedC}L}h#yd#yfAgz#}gAaZi_#m}#mcBwyAaj#_bBg|#csBm_Bo|BkaC{iBqsB_YqyBxEmtBks#aoB{RgLa~#bCcr#cLyoAemBeg#gt#_}#e`#on#uu#etA}vCqp#ubAklDgeGmxFiqHaqFoeHa[wbBu]}gAuoDeeG{uAooB_uAsy#om#ugAu_L{xSshEe_KieDm|KcfIcuWeUcOwy#aP{QuUg`BipF{P_l#klAgaEmjEs}NsvAiyFs}#izFjwAqrGtHkbCeB{cEql#g~CgSk|#mB}oAqNekEgw#cmDo_BgjFqqC}gH}`CwvG}cA{cB}nFowQ_t#an#efBmpE_oAsvCka#mwBk_CqbGuu#qfB{uAmrDivDw|E{nAqbDmpCyaJgdCejHk~#owAsw#adAm_#abA}Ven#qCou#cKeiBca#_cBmlAyjAsn#_kCk}#smDkVg{Bk}#gcHox#_sEaPwdC~KazF{EcpCrEmeGl]auBeEi~#yiAovCwwAgsC{i#oSsbAu~Ay_AmaBk_#iKak#mh#_BmBk#wHvG#dBvA"
}
};
var path = google.maps.geometry.encoding.decodePath(jsonData.overview_polyline.points);
console.log(path);
for (var i = 0; i < path.length; i++) {
bounds.extend(path[i]);
}
var polyline = new google.maps.Polyline({
path: path,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map
// strokeColor: "#0000FF",
// strokeOpacity: 1.0,
// strokeWeight: 2
});
polyline.setMap(map);
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>

How to add direction on tracking path for google maps

I am showing the tracking on map with marker points and line connecting them.
The problem is that i want to show the direction of travel on the links;
so I am not getting how to show the direction on the line between the marker points.
Is there any way to accomplish this task.
Showing the direction on the polyline can be accomplished with arrows.
There are some predefined paths that the google maps api3 provides.
See this section of the documentation -
SYMBOLS ON POLYLINE, that can be used other than an arrow.
Have a look at this fiddle that uses an arrow to indicate the direction on the polyline.
DEMO with a sigle symbol
You can also set the repeat property for the symbol so that it repeats for regular intervals.
DEMO with repeating symbols
JavaScript-
var iconsetngs = {
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
};
var polylineoptns = {
path: markers,
strokeOpacity: 0.8,
strokeWeight: 3,
map: map,
icons: [{
icon: iconsetngs,
offset: '100%'}]
};
polyline = new google.maps.Polyline(polylineoptns);
The interesting feature of this predefined symbol(the forward arrow specially) is that the arrow points towards the exact direction of which your co-ordinates are located. So, that obviously serves the purpose of denoting the direction in a Tracking System.
UPDATE: Not sure about the point you are trying to tell in the comments. The markers can be displayed the same way. Here is the code that adds markers with a loop and also set the polyline with arrows:
DEMO WITH MARKERS AND POLYLINE
Javascript:
var polylineoptns = {
strokeOpacity: 0.8,
strokeWeight: 3,
map: map,
icons: [{
repeat: '70px', //CHANGE THIS VALUE TO CHANGE THE DISTANCE BETWEEN ARROWS
icon: iconsetngs,
offset: '100%'}]
};
polyline = new google.maps.Polyline(polylineoptns);
var z = 0;
var path = [];
path[z] = polyline.getPath();
for (var i = 0; i < markers.length; i++) //LOOP TO DISPLAY THE MARKERS
{
var pos = markers[i];
var marker = new google.maps.Marker({
position: pos,
map: map
});
path[z].push(marker.getPosition()); //PUSH THE NEWLY CREATED MARKER'S POSITION TO THE PATH ARRAY
}