distance of a polyline - google-maps-api-3
I am working in a polyline and I need to obtain the distance of this. So if anyone can help I would be very gratefully.
Best regards.
This is my code:
function polyline() {
downloadUrl("xmlPolyline.asp", function(data) {
var xml = xmlParse(data);
var markersPath = xml.documentElement.getElementsByTagName("marker");
var path = [];
for (var i = 0; i < markersPath.length; i++) {
var lat = parseFloat(markersPath[i].getAttribute("lat"));
var lng = parseFloat(markersPath[i].getAttribute("lng"));
pointPath = new google.maps.LatLng(lat,lng);
path.push(pointPath);
}//finish loop
polyline = new google.maps.Polyline({
path: path,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
//new polyline
polyline.setMap(map);
}); //end download url
}
It's easy - using built in functions in the geometry library...
const polyLengthInMeters = google.maps.geometry.spherical.computeLength(yourPolyline.getPath().getArray());
To use the geometry library you declare it when you load the map api
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key={YOUR_KEY}&sensor=false&libraries=geometry"></script>
for more info see:
Google API Polyline reference
Google API mcvArray reference
Google API Spherical geometry reference
The "geometry" library has a computeDistanceBetween method.
This will return the result in meters:
var polylineLength = 0;
for (var i = 0; i < markersPath.length; i++) {
var lat = parseFloat(markersPath[i].getAttribute("lat"));
var lng = parseFloat(markersPath[i].getAttribute("lng"));
var pointPath = new google.maps.LatLng(lat,lng);
path.push(pointPath);
if (i > 0) polylineLength += google.maps.geometry.spherical.computeDistanceBetween(path[i], path[i-1]);
}
alert("the length of the polyline is "+polylineLength+" meters");
Update: There is now also a computeLength in the geometry library:
computeLength(path[, radius])
Parameters:
path: Array|MVCArray
radius: number optional
Return Value: number
Returns the length of the given path.
const polyline = new google.maps.Polyline({
path: polylineCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
var polylineLength = google.maps.geometry.spherical.computeLength(polyline.getPath());
proof of concept fiddle
code snippet:
// This example creates a 2-pixel-wide red polyline showing the path of
// a drive from New York, NY to Newark, NJ
function initMap() {
const map = new google.maps.Map(document.getElementById("map"),{
center: {lat:40.71248,lng: -74.006200},
zoom: 10
});
const polyline = new google.maps.Polyline({
path: polylineCoordinates,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
map: map
});
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < polyline.getPath().getLength(); i++) {
console.log(polyline.getPath().getAt(i).toUrlValue(6));
bounds.extend(polyline.getPath().getAt(i));
}
map.fitBounds(bounds);
var polylineLength = google.maps.geometry.spherical.computeLength(polyline.getPath());
document.getElementById('info').innerHTML = polylineLength.toFixed(2)+" meters, "+(polylineLength/1000).toFixed(2)+" km, "+(polylineLength/1609).toFixed(2)+" miles";
console.log(polylineLength.toFixed(2)+" meters, "+(polylineLength/1000).toFixed(2)+" km, "+(polylineLength/1609).toFixed(2)+" miles");
}
// per Google Directions service 13.9 mi. About 31 mins
// 13.9 mi = 22.36988 km
const polylineCoordinates = [
{lat:40.712480,lng:-74.006200},
{lat:40.712450,lng:-74.006150},
{lat:40.712310,lng:-74.005810},
{lat:40.712300,lng:-74.005810},
{lat:40.712300,lng:-74.005800},
{lat:40.712290,lng:-74.005790},
{lat:40.712280,lng:-74.005780},
{lat:40.712260,lng:-74.005770},
{lat:40.712250,lng:-74.005770},
{lat:40.712130,lng:-74.005700},
{lat:40.712130,lng:-74.005700},
{lat:40.712090,lng:-74.005830},
{lat:40.712050,lng:-74.005970},
{lat:40.712020,lng:-74.006090},
{lat:40.711980,lng:-74.006230},
{lat:40.711930,lng:-74.006390},
{lat:40.711930,lng:-74.006440},
{lat:40.711830,lng:-74.006810},
{lat:40.711800,lng:-74.006950},
{lat:40.711770,lng:-74.007050},
{lat:40.711690,lng:-74.007420},
{lat:40.711670,lng:-74.007480},
{lat:40.711660,lng:-74.007510},
{lat:40.711660,lng:-74.007550},
{lat:40.711660,lng:-74.007570},
{lat:40.711660,lng:-74.007600},
{lat:40.711660,lng:-74.007650},
{lat:40.711670,lng:-74.007690},
{lat:40.711680,lng:-74.007710},
{lat:40.711690,lng:-74.007740},
{lat:40.711710,lng:-74.007780},
{lat:40.711710,lng:-74.007780},
{lat:40.711750,lng:-74.007840},
{lat:40.711800,lng:-74.007920},
{lat:40.711850,lng:-74.007990},
{lat:40.711870,lng:-74.008010},
{lat:40.711910,lng:-74.008050},
{lat:40.711950,lng:-74.008070},
{lat:40.711970,lng:-74.008090},
{lat:40.712000,lng:-74.008120},
{lat:40.712080,lng:-74.008270},
{lat:40.712380,lng:-74.008930},
{lat:40.712470,lng:-74.009130},
{lat:40.712650,lng:-74.009520},
{lat:40.712730,lng:-74.009680},
{lat:40.712730,lng:-74.009680},
{lat:40.712790,lng:-74.009650},
{lat:40.713280,lng:-74.009260},
{lat:40.713430,lng:-74.009140},
{lat:40.713810,lng:-74.008840},
{lat:40.714270,lng:-74.008480},
{lat:40.714370,lng:-74.008400},
{lat:40.714890,lng:-74.008000},
{lat:40.714940,lng:-74.007970},
{lat:40.715200,lng:-74.007750},
{lat:40.715440,lng:-74.007560},
{lat:40.715480,lng:-74.007520},
{lat:40.715960,lng:-74.007150},
{lat:40.716000,lng:-74.007110},
{lat:40.716040,lng:-74.007070},
{lat:40.716530,lng:-74.006680},
{lat:40.717080,lng:-74.006240},
{lat:40.717170,lng:-74.006180},
{lat:40.717600,lng:-74.005830},
{lat:40.717680,lng:-74.005770},
{lat:40.717780,lng:-74.005680},
{lat:40.717870,lng:-74.005620},
{lat:40.717960,lng:-74.005540},
{lat:40.717960,lng:-74.005540},
{lat:40.718020,lng:-74.005530},
{lat:40.718050,lng:-74.005520},
{lat:40.718110,lng:-74.005480},
{lat:40.718180,lng:-74.005430},
{lat:40.718230,lng:-74.005390},
{lat:40.718270,lng:-74.005380},
{lat:40.718300,lng:-74.005360},
{lat:40.718330,lng:-74.005340},
{lat:40.718370,lng:-74.005320},
{lat:40.718410,lng:-74.005300},
{lat:40.718600,lng:-74.005230},
{lat:40.718670,lng:-74.005220},
{lat:40.718880,lng:-74.005180},
{lat:40.718940,lng:-74.005180},
{lat:40.719010,lng:-74.005170},
{lat:40.719060,lng:-74.005170},
{lat:40.719110,lng:-74.005170},
{lat:40.719370,lng:-74.005180},
{lat:40.719730,lng:-74.005200},
{lat:40.719850,lng:-74.005190},
{lat:40.719950,lng:-74.005190},
{lat:40.720280,lng:-74.005180},
{lat:40.720480,lng:-74.005190},
{lat:40.720630,lng:-74.005210},
{lat:40.721030,lng:-74.005250},
{lat:40.721380,lng:-74.005280},
{lat:40.721470,lng:-74.005280},
{lat:40.721740,lng:-74.005330},
{lat:40.721830,lng:-74.005340},
{lat:40.721930,lng:-74.005360},
{lat:40.722090,lng:-74.005380},
{lat:40.722130,lng:-74.005390},
{lat:40.722180,lng:-74.005390},
{lat:40.722230,lng:-74.005380},
{lat:40.723010,lng:-74.005060},
{lat:40.723630,lng:-74.004810},
{lat:40.723630,lng:-74.004810},
{lat:40.723650,lng:-74.004890},
{lat:40.723660,lng:-74.005000},
{lat:40.723670,lng:-74.005050},
{lat:40.723690,lng:-74.005280},
{lat:40.723710,lng:-74.005440},
{lat:40.723730,lng:-74.005700},
{lat:40.723760,lng:-74.005980},
{lat:40.723760,lng:-74.005980},
{lat:40.723810,lng:-74.006060},
{lat:40.723820,lng:-74.006150},
{lat:40.723840,lng:-74.006250},
{lat:40.723850,lng:-74.006290},
{lat:40.723860,lng:-74.006310},
{lat:40.723870,lng:-74.006360},
{lat:40.723890,lng:-74.006420},
{lat:40.723910,lng:-74.006470},
{lat:40.723940,lng:-74.006530},
{lat:40.723970,lng:-74.006590},
{lat:40.724000,lng:-74.006640},
{lat:40.724010,lng:-74.006670},
{lat:40.724030,lng:-74.006690},
{lat:40.724070,lng:-74.006740},
{lat:40.724110,lng:-74.006800},
{lat:40.724150,lng:-74.006840},
{lat:40.724200,lng:-74.006890},
{lat:40.724210,lng:-74.006900},
{lat:40.724240,lng:-74.006930},
{lat:40.724270,lng:-74.006950},
{lat:40.724300,lng:-74.006960},
{lat:40.724330,lng:-74.006980},
{lat:40.724360,lng:-74.006990},
{lat:40.724390,lng:-74.006990},
{lat:40.724440,lng:-74.006990},
{lat:40.724500,lng:-74.006990},
{lat:40.724580,lng:-74.006990},
{lat:40.724620,lng:-74.006990},
{lat:40.724710,lng:-74.007010},
{lat:40.724770,lng:-74.007000},
{lat:40.724850,lng:-74.006990},
{lat:40.724850,lng:-74.006980},
{lat:40.724890,lng:-74.006980},
{lat:40.724960,lng:-74.006970},
{lat:40.725010,lng:-74.006970},
{lat:40.725070,lng:-74.006970},
{lat:40.725120,lng:-74.006970},
{lat:40.725190,lng:-74.006960},
{lat:40.725290,lng:-74.006960},
{lat:40.725370,lng:-74.006980},
{lat:40.725420,lng:-74.006990},
{lat:40.725510,lng:-74.007020},
{lat:40.725580,lng:-74.007070},
{lat:40.725610,lng:-74.007110},
{lat:40.725640,lng:-74.007170},
{lat:40.725660,lng:-74.007220},
{lat:40.725690,lng:-74.007320},
{lat:40.725720,lng:-74.007420},
{lat:40.725720,lng:-74.007440},
{lat:40.725740,lng:-74.007560},
{lat:40.725750,lng:-74.007670},
{lat:40.725780,lng:-74.007910},
{lat:40.725800,lng:-74.008140},
{lat:40.725820,lng:-74.008270},
{lat:40.725830,lng:-74.008380},
{lat:40.725850,lng:-74.008600},
{lat:40.725850,lng:-74.008610},
{lat:40.725870,lng:-74.008750},
{lat:40.725880,lng:-74.008850},
{lat:40.725900,lng:-74.009080},
{lat:40.725930,lng:-74.009320},
{lat:40.725950,lng:-74.009540},
{lat:40.725950,lng:-74.009550},
{lat:40.726010,lng:-74.010020},
{lat:40.726010,lng:-74.010040},
{lat:40.726070,lng:-74.010490},
{lat:40.726190,lng:-74.011430},
{lat:40.726220,lng:-74.011670},
{lat:40.726260,lng:-74.012150},
{lat:40.726320,lng:-74.012590},
{lat:40.726350,lng:-74.012820},
{lat:40.726360,lng:-74.012840},
{lat:40.726390,lng:-74.013070},
{lat:40.726420,lng:-74.013290},
{lat:40.726450,lng:-74.013540},
{lat:40.726640,lng:-74.014940},
{lat:40.726690,lng:-74.015300},
{lat:40.726730,lng:-74.015540},
{lat:40.726870,lng:-74.016470},
{lat:40.726950,lng:-74.016930},
{lat:40.726980,lng:-74.017160},
{lat:40.727020,lng:-74.017400},
{lat:40.727200,lng:-74.018560},
{lat:40.727270,lng:-74.019020},
{lat:40.727570,lng:-74.020930},
{lat:40.727700,lng:-74.021810},
{lat:40.727740,lng:-74.022040},
{lat:40.727990,lng:-74.023670},
{lat:40.728030,lng:-74.023900},
{lat:40.728070,lng:-74.024140},
{lat:40.728210,lng:-74.025070},
{lat:40.728390,lng:-74.026230},
{lat:40.728500,lng:-74.026930},
{lat:40.728550,lng:-74.027510},
{lat:40.728570,lng:-74.027750},
{lat:40.728600,lng:-74.027990},
{lat:40.728680,lng:-74.028930},
{lat:40.728700,lng:-74.029160},
{lat:40.728830,lng:-74.030580},
{lat:40.728870,lng:-74.031050},
{lat:40.728900,lng:-74.031350},
{lat:40.728940,lng:-74.031760},
{lat:40.728940,lng:-74.031790},
{lat:40.728960,lng:-74.032020},
{lat:40.728970,lng:-74.032030},
{lat:40.728990,lng:-74.032150},
{lat:40.729020,lng:-74.032330},
{lat:40.729070,lng:-74.032480},
{lat:40.729110,lng:-74.032580},
{lat:40.729160,lng:-74.032720},
{lat:40.729170,lng:-74.032760},
{lat:40.729270,lng:-74.033070},
{lat:40.729530,lng:-74.033860},
{lat:40.729960,lng:-74.035160},
{lat:40.730040,lng:-74.035410},
{lat:40.730060,lng:-74.035460},
{lat:40.730120,lng:-74.035590},
{lat:40.730150,lng:-74.035680},
{lat:40.730190,lng:-74.035780},
{lat:40.730220,lng:-74.035840},
{lat:40.730290,lng:-74.035950},
{lat:40.730330,lng:-74.036020},
{lat:40.730400,lng:-74.036100},
{lat:40.730590,lng:-74.036330},
{lat:40.730710,lng:-74.036500},
{lat:40.730780,lng:-74.036580},
{lat:40.730840,lng:-74.036670},
{lat:40.730910,lng:-74.036780},
{lat:40.730970,lng:-74.036880},
{lat:40.731030,lng:-74.036980},
{lat:40.731040,lng:-74.037000},
{lat:40.731100,lng:-74.037100},
{lat:40.731140,lng:-74.037200},
{lat:40.731160,lng:-74.037240},
{lat:40.731220,lng:-74.037360},
{lat:40.731320,lng:-74.037580},
{lat:40.731340,lng:-74.037630},
{lat:40.731360,lng:-74.037680},
{lat:40.731380,lng:-74.037740},
{lat:40.731390,lng:-74.037800},
{lat:40.731450,lng:-74.038480},
{lat:40.731470,lng:-74.038720},
{lat:40.731540,lng:-74.039420},
{lat:40.731560,lng:-74.039510},
{lat:40.731590,lng:-74.039710},
{lat:40.731610,lng:-74.039940},
{lat:40.731620,lng:-74.040130},
{lat:40.731710,lng:-74.041100},
{lat:40.731710,lng:-74.041100},
{lat:40.731560,lng:-74.041130},
{lat:40.731430,lng:-74.041150},
{lat:40.731270,lng:-74.041170},
{lat:40.731210,lng:-74.041180},
{lat:40.731050,lng:-74.041200},
{lat:40.730820,lng:-74.041240},
{lat:40.730800,lng:-74.041240},
{lat:40.730720,lng:-74.041250},
{lat:40.730480,lng:-74.041300},
{lat:40.730350,lng:-74.041310},
{lat:40.730180,lng:-74.041330},
{lat:40.730180,lng:-74.041330},
{lat:40.730130,lng:-74.040980},
{lat:40.730110,lng:-74.040900},
{lat:40.730070,lng:-74.040660},
{lat:40.730040,lng:-74.040520},
{lat:40.730030,lng:-74.040430},
{lat:40.730010,lng:-74.040300},
{lat:40.730000,lng:-74.040170},
{lat:40.729970,lng:-74.039910},
{lat:40.729950,lng:-74.039720},
{lat:40.729950,lng:-74.039720},
{lat:40.729520,lng:-74.039790},
{lat:40.729380,lng:-74.039810},
{lat:40.729330,lng:-74.039820},
{lat:40.729210,lng:-74.039840},
{lat:40.729200,lng:-74.039840},
{lat:40.729180,lng:-74.039850},
{lat:40.728980,lng:-74.039880},
{lat:40.728960,lng:-74.039880},
{lat:40.728960,lng:-74.039890},
{lat:40.728950,lng:-74.039890},
{lat:40.728940,lng:-74.039890},
{lat:40.728670,lng:-74.039940},
{lat:40.728300,lng:-74.040000},
{lat:40.727960,lng:-74.040060},
{lat:40.727790,lng:-74.040090},
{lat:40.727630,lng:-74.040040},
{lat:40.727270,lng:-74.040110},
{lat:40.726690,lng:-74.040200},
{lat:40.726640,lng:-74.040200},
{lat:40.726510,lng:-74.040220},
{lat:40.726480,lng:-74.040230},
{lat:40.725800,lng:-74.040330},
{lat:40.725380,lng:-74.040400},
{lat:40.725200,lng:-74.040420},
{lat:40.725120,lng:-74.040430},
{lat:40.725010,lng:-74.040450},
{lat:40.724810,lng:-74.040490},
{lat:40.724680,lng:-74.040510},
{lat:40.724090,lng:-74.040590},
{lat:40.723620,lng:-74.040660},
{lat:40.723240,lng:-74.040720},
{lat:40.723000,lng:-74.040760},
{lat:40.722910,lng:-74.040770},
{lat:40.722240,lng:-74.040890},
{lat:40.721780,lng:-74.040960},
{lat:40.721500,lng:-74.041000},
{lat:40.721260,lng:-74.041020},
{lat:40.720810,lng:-74.041090},
{lat:40.720110,lng:-74.041200},
{lat:40.719820,lng:-74.041250},
{lat:40.719640,lng:-74.041290},
{lat:40.719260,lng:-74.041340},
{lat:40.719020,lng:-74.041370},
{lat:40.718740,lng:-74.041410},
{lat:40.718690,lng:-74.041480},
{lat:40.718600,lng:-74.041620},
{lat:40.718390,lng:-74.041960},
{lat:40.718290,lng:-74.042110},
{lat:40.718270,lng:-74.042130},
{lat:40.718250,lng:-74.042150},
{lat:40.718230,lng:-74.042170},
{lat:40.718200,lng:-74.042180},
{lat:40.718150,lng:-74.042200},
{lat:40.717990,lng:-74.042240},
{lat:40.717840,lng:-74.042270},
{lat:40.717760,lng:-74.042290},
{lat:40.717650,lng:-74.042310},
{lat:40.717650,lng:-74.042310},
{lat:40.717700,lng:-74.042740}
];
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 90%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<title>Simple Polylines</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=geometry&v=weekly"
defer
></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="info"></div>
<div id="map"></div>
</body>
</html>
Related
HERE maps: show both clustered and not clustered points
My goal is to display a group of clustered data points and one data point of different nature that never goes to a cluster in the same layer, so they all can received hover mouse events. Is it possible to tell H.clustering.Provider to always exclude some points from clusters, or create a custom H.map.provider.ObjectProvider that can do it? P. S. I tried creating two layers and setting pointer-events: none for them in CSS to catch hover events by all points, it worked but made the map too slow to use. Update Here is a demo code, the goal is to get a hover rectangle for both markers with a condition that the first market should never be included to a cluster <html> <head> <script src="http://js.api.here.com/v3/3.0/mapsjs-core.js" type="text/javascript" charset="utf-8"></script> <script src="http://js.api.here.com/v3/3.0/mapsjs-service.js" type="text/javascript" charset="utf-8"></script> <script src="http://js.api.here.com/v3/3.0/mapsjs-clustering.js" type="text/javascript" charset="utf-8"></script> <style> svg:hover { border: 2px solid red; } </style> </head> <body> <div id="mapContainer"/> <script> var platform = new H.service.Platform({ 'app_id': 'my id', 'app_code': 'my code' }); var defaultLayers = platform.createDefaultLayers(); var map = new H.Map( document.getElementById('mapContainer'), defaultLayers.normal.map, { zoom: 10, center: { lat: 51.5, lng: 13.4 } }); //this marker should not go to clusters var marker = new H.map.DomMarker({ lat: 51.5, lng: 13.4 }); map.addObject(marker); //this marker should go to clusters if there is more data points var dataPoints = []; dataPoints.push(new H.clustering.DataPoint(51.5, 13.45)); var theme = { getClusterPresentation: function(cluster){ return new H.map.DomMarker(cluster.getPosition(), {}); }, getNoisePresentation: function(point){ return new H.map.DomMarker(point.getPosition(), {}); } } var clusteredDataProvider = new H.clustering.Provider(dataPoints, { theme: theme, }); var layer = new H.map.layer.ObjectLayer(clusteredDataProvider); map.addLayer(layer); </script> </body> </html>
The following example shows a cluster provider initialized with the parameters eps and minWeight. eps holds the value of the radius within which data points are considered for clustering, while minWeight holds the cumulative weight that points lying close to another must reach or exceed to be clustered. The value of minWeight is 3 in the example, which means that three points, each with the weight of one or two data points with the weight of 2 and 1, respectively, form a cluster. This will reduce the time of rendering the page. Also please refer the new documentation : https://developer.here.com/documentation/examples/maps-js/clustering/marker-clustering var clusteredDataProvider = new H.clustering.Provider(dataPoints, { min: 4, max: 10, clusteringOptions: { eps: 32, minWeight: 3 } });
Display geoserver WMS layer on Google MAP where datasource for Geoserver is PostGreSQL
I am working on a web application of ASP.NET with the following API/tools Google Map, GeoServer, PostGreSQL(With POSTGIS). I have a requirement to display WMS layer of GeoServer on the google map V3.26.Data source of GeoServer is POSTGIS. I have inserted hundreds of MULTILINESTRING in PostGreSQL(With POSTGIS) using the below given scripts. INSERT INTO public."LineData"("ID", "LineCoordinates") values('11195625',ST_GEOMFROMTEXT('MULTILINESTRING ((<Latitude Longitude>))',4326)); Then publish a layer in Geoserver that use the data from "LineData" table and keep Native SRC EPSG:4326. To display this layer on Google Map V3.26, I have used the below given code. The problem is that tiles are not rendering correctly. They are broken and shown at wrong places. Can anyone tell what wrong I am doing? <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Google Map with Geoserver WMS Overlay</title> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.26&language=en-US"></script> <style type="text/css"> html { height: 100%; } body { height: 100%; margin: 0px; padding: 0px; } #map_canvas { height: 100%; } </style> </head> <body onload="initialize()"> <h1>Google Map with Geoserver WMS and KML Overlay</h1> <div id="map_canvas"></div> </body> </html> <script type="text/javascript"> var TILE_SIZE = 256; var wmsparams = [ "SERVICE=WMS", "VERSION=1.1.1", "REQUEST=GetMap", "FORMAT=image/png", "TRANSPARENT=TRUE", "BGCOLOR=0xFFFFFF", "SRS=EPSG:4326", "WIDTH=256", "HEIGHT=256" ]; </script> <script type="text/javascript"> function initialize() { // Create a MapOptions object with the required properties for base map var mapOptions = { zoom: 9, center: new google.maps.LatLng(36.04450, -80.34747), mapTypeId: google.maps.MapTypeId.ROADMAP }; // Create the base map map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); //Define custom WMS layer for census output areas in WGS84 var censusLayer = new google.maps.ImageMapType( { getTileUrl: function (coord, zoom) { // Compose URL for overlay tile var s = Math.pow(2, zoom); var twidth = 256; var theight = 256; //latlng bounds of the 4 corners of the google tile //Note the coord passed in represents the top left hand (NW) corner of the tile. var gBl = map.getProjection().fromPointToLatLng(new google.maps.Point(coord.x * twidth / s, (coord.y + 1) * theight / s)); // bottom left / SW var gTr = map.getProjection().fromPointToLatLng(new google.maps.Point((coord.x + 1) * twidth / s, coord.y * theight / s)); // top right / NE // Bounding box coords for tile in WMS pre-1.3 format (x,y) var bbox = parseFloat(gBl.lat()) + "," + parseFloat(gBl.lng()) + "," + parseFloat(gTr.lat()) + "," + parseFloat(gTr.lng()); //base WMS URL var url = "http://localhost:8080/geoserver/TestWorkSpace/wms?"; url += "&service=WMS"; //WMS service url += "&version=1.1.0"; //WMS version url += "&request=GetMap"; //WMS operation url += "&layers=TestLayer"; //WMS layers to draw url += "&styles="; //use default style url += "&format=image/png"; //image format url += "&TRANSPARENT=TRUE"; //only draw areas where we have data url += "&srs=EPSG:4326"; //projection WGS84 url += "&bbox=" + bbox; //set bounding box for tile url += "&width=256"; //tile size used by google url += "&height=256"; //url += "&tiled=true"; return url; //return WMS URL for the tile }, tileSize: new google.maps.Size(256, 256), opacity: 0.85, isPng: true }); // add WMS layer to map map.overlayMapTypes.push(censusLayer); } </script> Thanks
You are asking GeoServer to return you the tiles in epsg:4326 while your map is in epsg:3857, hence they look wrong. So you need to change the line: url += "&srs=EPSG:4326"; to url += "&srs=EPSG:3875"; You also need to specify the bounding box in your map coordinates.
Google Maps: how to efficiently change marker when mouseover
I want to dynamically change the color/text of any google maps marker. Run the code: http://jsbin.com/odimop/edit#javascript,html,live As you can see the problem of using a variable (var styloo) is when properties change then all markers using that variable behave in the same way, in this case marker4 and marker5. This approach is cumbersome and tedious when the map has too many markers because each marker will need one styled variable I'm looking for a solution that use something like: this.styleIcon.color = "00ff00";. But so far is not working. Any idea? please! <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/styledmarker/src/StyledMarker.js"></script> <script type="text/javascript"> var styleIcon; function initialize() { var myLatLng = new google.maps.LatLng(37.313477473067, -121.880502070713); var myOptions = { zoom: 10, center: myLatLng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var marker2 = new StyledMarker({styleIcon:new StyledIcon(StyledIconTypes.BUBBLE,{color:"00ffff",text:"Hover Me, this doesn't work"}),position:new google.maps.LatLng(37.5, -121.880502070713),map:map}); var marker3 = new StyledMarker({styleIcon:new StyledIcon(StyledIconTypes.BUBBLE,{color:"ff0000",text:"Just a Marker"}),position:new google.maps.LatLng(37.4, -121.880502070713),map:map}); google.maps.event.addDomListener(marker2,"mouseover", function(o){ this.setAnimation(google.maps.Animation.BOUNCE); this.styleIcon.color = "00ff00"; this.styleIcon.text = "it does not change :("; }); styloo = new StyledIcon(StyledIconTypes.BUBBLE,{color:"#95AA7B",text:"click me!",fore:"#ffffff"}); var marker4 = new StyledMarker({styleIcon: styloo,position:new google.maps.LatLng(37.2, -121.88),map:map}); var marker5 = new StyledMarker({styleIcon: styloo,position:new google.maps.LatLng(37.1, -121.88),map:map}); google.maps.event.addDomListener(marker4,"click", function(o){ this.setAnimation(google.maps.Animation.BOUNCE); styloo.set("fore","#ffffff");//test color styloo.set("color","#C2554D");// background color styloo.set("text","color changed"); }); } </script> </head> <body style="margin:0px; padding:0px;" onload="initialize()"> <div id="map_canvas" style="width: 600px; height: 600px;"></div> </body>
As per StyledMarker examples, you need to use the set(property, value) methods, like this: styleIcon.set("text","Elevation: " + results[0].elevation + "m"); In your case, change the mouseover handler to this: this.styleIcon.set('color', '00ff00'); this.styleIcon.set('text', 'it does not change :('); As for the other problem, where both change at once, you'll need to create a StyledIcon for each StyledMarker. I'd just add a function that returns a new icon each time. function createStyle() { return new StyledIcon(StyledIconTypes.BUBBLE,{color:"#95AA7B",text:"click me!",fore:"#ffffff"}); } var marker4 = new StyledMarker({styleIcon: createStyle(),position:new google.maps.LatLng(37.2, -121.88),map:map}); var marker5 = new StyledMarker({styleIcon: createStyle(),position:new google.maps.LatLng(37.1, -121.88),map:map}); google.maps.event.addDomListener(marker4,"click", function(o){ this.setAnimation(google.maps.Animation.BOUNCE); this.styleIcon.set("fore","#ffffff");//test color this.styleIcon.set("color","#C2554D");// background color this.styleIcon.set("text","color changed"); });
Google Maps api v3 - circle without fill or unclickable fill
.. and sorry for my english. I'm trying to create circle without fill with google maps api v3. I know that I can set opacity (and fill disapired), but this no-visible fill is still clickable. I need to set fill unclickable, but stroke have to be clickable. Under my circle there are few points and lines, that have to be clickable and circle is upper, than lines, for example. My idea was move circle to different pane, but I didn't find way how to do it. Is there a solution for it? Thanks! Ajax [EDIT] Here is code sample. My problem is, that I'm not able to click on map or line inside blue circle. <!DOCTYPE html> <html> <head> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0; padding: 0 } #map_canvas { height: 100% } </style> <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=YOUR_GMAP+API_KEY&sensor=true"> </script> <script type="text/javascript"> function initialize() { var lat = 49; var lon = 15; var myOptions = { center: new google.maps.LatLng(lat,lon), zoom: 18, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); google.maps.event.addListener(map, "click", function(clickEvt) { alert('mapClicked'); }); var line = new google.maps.Polyline({ path: [new google.maps.LatLng(lat + 0.001, lon + 0.001),new google.maps.LatLng(lat - 0.001, lon - 0.001)], strokeColor: '#00FF00', map: map }); google.maps.event.addListener(line, "click", function() { alert('Line clicked'); }); var circle = new google.maps.Circle({ strokeColor: '#0000FF', strokeWeight: 2, fillOpacity: 0, map: map, center: new google.maps.LatLng(lat, lon), radius: 100 }); google.maps.event.addListener(circle, 'click', function(event) { alert('circle clicked'); }); } </script> </head> <body onload="initialize()"> <div id="map_canvas" style="width:100%; height:100%"></div> </body> </html>
set 'clickable: false` in the circle option object to allow the click event be detected in the map layer. var circle = new google.maps.Circle({ strokeColor: '#0000FF', strokeWeight: 2, fillOpacity: 0, map: map, center: new google.maps.LatLng(lat, lon), radius: 100, clickable: false }); reference: Unclickable fill in Circle?
Try this: draw 2 circles, one for your outline (clickable) and one for your fill (not clickable). The fill circle should be slightly smaller, and set its z-index to sit on top of the other one, preventing you clicking on anything but the outline circle. The problem will be the other items you want to remain clickable underneath the circle.
How do I get a reference to the polygon clicked? (google maps api v3)
I've set up some polygons, drew them on the map just fine. I also managed to fire console.log when they were clicked. However, how would I go on about figuring out which polygon was actually clicked? As you can see in my sample code here I store each object within the collection "lots", however - clicking them only gives me the lat-long of the click. I figured I might need to loop through my polygons and check if the point was clicked is intersecting them and thus figure out which polygon it is... is there an easier solution? var lot = new google.maps.Polygon({ paths: me.area, strokeColor: 'black', strokeOpacity: 0.35, strokeWeight: 1, fillColor: fillcol, fillOpacity: 0.35 }); lot.setMap(map); var obj = { 'id':me.id, 'rented':me.rented, 'area':lot }; google.maps.event.addListener(lot, 'click', function(event) { console.log(event); }); lots.push(lot);
Why don't assign to each polygon some id property when you create them and later just use this.myID? Truly speaking, you can hang all information you need on that polygon object. var lot = new google.maps.Polygon({ paths: me.area, strokeColor: 'black', strokeOpacity: 0.35, strokeWeight: 1, fillColor: fillcol, fillOpacity: 0.35 }); lot.setMap(map); var obj = { 'id':me.id, 'rented':me.rented, 'area':lot }; lot.objInfo = obj; google.maps.event.addListener(lot, 'click', function(event) { console.log(this.objInfo); }); lots.push(lot); It would be more effective than path comparison in a loop, or am i missing something? :)
If I can step in a little late with a different solution, I was having the same problem and discovered that you can define custom properties on a polygon. My example (which creates a state on a map of the U.S.) poly = new google.maps.Polygon({ map_state_id: map_state_id, paths: pts, fillColor: colour, fillOpacity: 0.66, strokeWeight: 1, clickable:true }); In this case "map_state_id" is the custom property. I have defined it to be the ID of the state (1 for Alabama, 2 for Alaska, etc.) Then when the particular state is clicked later, this "map_state_id" can be passed into the event function. google.maps.event.addListener(poly, 'click', function() { var map_state_id = this.map_state_id; //retrieve correct state_id $.ajax( { type: "POST", url: "http://www...get_state_info.php", data: {state_id : map_state_id}, dataType: "html", success: function(data) { $("#state_info").html(data); //display some info } }); }); I found this particular concept at http://dominoc925.blogspot.com/2011/12/add-your-own-property-field-to-google.html
Turned out getPath() works like a charm. I did not realize I actually got the polygon reference passed on the click event, to match this with my stored "lots" I simply loop through my stored lots and compare this.getPath to other.getPath, if they match I know which lot was clicked and can now show info related to this particular object. Here's a code sample: (where parking is an array of my parking area objects which themselves have arrays containing parking lot objects) google.maps.event.addListener(lot, 'click', function(event) { var myPath = this.getPath(); for(var i = 0; i < parking.length; i++){ for(var j = 0; j < parking[i].lots.length; j++){ var lot = parking[i].lots[j]; var otherPath = lot.poly.getPath(); if(otherPath == myPath){ console.log(lot); break; } } } });