Drawing many lines with GoogleMaps API - javascript

I'm trying to use the JavaScript API for GoogleMaps to draw a bunch of lines but I keep getting syntax errors I don't understand. My data is stored as such:
var line_map = {};
line_map['l1'] = {
path: [new google.maps.LatLng(42.3581, -71.0636), new google.maps.LatLng(42.351821, -71.045461)],
weight: 2
};
With many other line entries. I then try to use it with the following:
for (var entry in line_map) {
var line = new google.maps.Polyline({
path: entry.path,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: entry.weight
});
// Add the line to map
line.setMap(map);
}
However I keep getting an error that says Invalid value for constructor parameter 0: undefined
I get that it's saying entry.path is undefined but I don't understand why because I clearly defined it in the entry for l1

You should change this:
path: entry.path
to
path: line_map[entry].path
And do the same with the weight. Check out this working fiddle - I changed some coordinates to see the line.
EDIT: There is also a good explanation on this post about the for...in loop and objects.

Related

changing google maps polygon vertices

Just a quick query - I'm sure it has a quick answer :)
I'm trying to loop through an array of points defining a polygon in google maps and change them (my test programme is just decrementing the latitude by a small amount, to see if I can get it to work). I've taken my experimental code from the Bermuda Triangle example, but with a LatLong array rather than MVC.
triangleCoords = [
new google.maps.LatLng(25.774, -80.190 ),
new google.maps.LatLng(18.466, -66.118 ),
new google.maps.LatLng(32.321, -64.757 )
];
bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map
});
And I'm trying to alter the points with this:
var vertices = bermudaTriangle.getPath();
for (var i =0; i < vertices.getLength(); i++) {
var xy = vertices.getAt(i);
vertices.setAt(i, new google.maps.LatLng( xy.lat()-0.01, xy.lng() ));
}
But it doesn't work. Can anyone see what is wrong? Thanks
You've got an array of coordinates, saved as the variable vertices, which you've then updated with new values... and then what? All you've done is update an array.
If you want to redraw the polygon, you also need to then do:
bermudaTriangle.setPath(vertices);

Google Maps - Unable to draw Polygons and Linestrings

I'm building an application using MEAN Stack and Google Maps Api and I'm having a little problem when it comes to draw Polygons and LineStrings.
I have a collection of geometries (Points, Polygons and LineStrings) and each time I find one of them I need to add it properly to the map.
I have no problem when it comes to render Markers but I have issues when it comes to Polygons and LineStrings.
Here's my code which contains the logic of initializing the map.
// Initializes the map
function initialize(latitude, longitude, filter) {
// If map has not been created...
if (!map) {
// Create a new map and place in the index.html page
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: new google.maps.LatLng(vm.selectedLat, vm.selectedLong)
});
}
// Loop through each location in the array and place a geometry
locations.forEach(function (n) {
if(n.type === 'LineString'){
console.log('LineString '+JSON.stringify(n.coords));
var linestring = new google.maps.Polyline({
position: n.coords,
map: map,
geodesic: true,
strokeColor: '#0404B4',
strokeOpacity: 1.0,
strokeWeight: 2
});
// For each linestring created, add a listener
google.maps.event.addListener(linestring, 'click', function () {
// When clicked, open the selected linestring's message
n.message.open(map, linestring);
});
linestring.setMap(map);
}
if(n.type === 'Polygon'){
console.log('Polygon '+JSON.stringify(n.coords));
var polygon = new google.maps.Polygon({
path: n.coords,
geodesic: true,
strokeColor: '#0404B4',
strokeOpacity: 0.8,
strokeWeight: 3,
fillColor: '#0404B4',
fillOpacity: 0.35
});
// For each polygon created, add a listener
google.maps.event.addListener(polygon, 'click', function () {
// When clicked, open the selected polygon's message
n.message.open(map, polygon);
});
polygon.setMap(map);
}
});
};
Here are the screenshots of the two console.log() of the coordinates
As you can see from the screenshot I also get
InvalidValueError: at index 0: not a LatLng or LatLngLiteral: in property lat: not a number
I tried, unsuccessfully, to find a solution to that.
Why can't I draw these geometries? How can I solve the InvalidValueError?
Thanks in advance.
Issues:
A google.maps.Polyline doesn't have a position property, it has a path property which takes an array of google.maps.LatLngLiterals (which looks like what you are passing in to the position property).
A google.maps.Polygon has a paths property which takes an array of google.maps.LatLngLiterals, but your data is not formatted correctly (and you are using path not paths). It is an array of {lat: [46.774, -48.19], lng: [46.466, -29.119]}, neither lat nor lng are Numbers, they are arrays.

Adding Properties to Global Objects

I know this is a common question, and I'm a JS newbie, but I'm completely stumped even after searching StackOverflow for hours.
I'm using the Google Maps API, and want to keep track of my markers by association with an ID. So I have var pinArray = new Object() as a global variable, and add markers like this:
function CreateMarkers (data){
data.forEach(function(store) {
<!-- CREATE MAP MARKER -->
var mapLat = store.latitude;
var mapLong = store.longitude;
var mapLatLng = { lat: parseFloat(mapLat), lng: parseFloat(mapLong) };
var marker = new google.maps.Marker({
position: mapLatLng,
title: store.name,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 8.5,
fillColor: 'Green',
fillOpacity: 0.8,
strokeWeight: 0.6,
},
zIndex: 0
});
cluster.addMarker(marker);
var key = store.Id;
pinArray['${key}'] = marker;
})
}
Where cluster is var cluster = new MarkerClusterer(map);.
When I try to do console.log(pinArray); back outside of the function, I get an empty object: Object {}. I've tried not using string interpolation as well, like pinArray[store.Id] = marker;, but get the same problem.
I need to keep this global associate between pins and IDs because I need to reference and update markers by their ID in other functions. Or at least, I think I do, I'm open to other ways of doing this. Help is very much appreciated; thank you in advance.
Typically when I've done something like this in the past I'll use a standard javascript array instead of an ID'd object:
var pinArray = [];
Then use push to add the markers to it as you go:
pinArray.push(Marker);
When you create the pin you can include your key in its property definition:
var marker = new google.maps.Marker({
position: mapLatLng,
title: store.name,
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 8.5,
fillColor: 'Green',
fillOpacity: 0.8,
strokeWeight: 0.6,
},
zIndex: 0,
key: store.Id
});
and you can write a simple looping lookup function to find the individual map marker if you need to pull them by ID. Something like:
function GetMarkerByKey(key) {
var i = 0;
while (pinArray[i].key != key) {i++}
return pinArray[i];
}
Also, if you're using it in a dynamic event handler for click or hover you can use the this property to identify which marker they are activating it with.
~~~Edited to fix a syntax error~~~
var pinArray assigns the variable within the scope of function it's defined. The safest way to ensure you're defining a variable as global, regardless of where you are inside a function, is to assign it to window.
window.pinArray = new Object();

I want to create a Donut with Javascript API V3(Empty space inside like a hole)

I want to create a hole in my Javascript Google API V3, so i follow Beginning Google Map API V3. But the code is rendering the whole area. Here is my Javascript code.
(function() {
window.onload = function() {
// Creating a map
var options = {
zoom: 6,
center: new google.maps.LatLng(36.5, -79.8),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'), options);
// Creating an array with the points for the outer polygon
var polyOuter = [
new google.maps.LatLng(37.303, -81.256),
new google.maps.LatLng(37.303, -78.333),
new google.maps.LatLng(35.392, -78.333),
new google.maps.LatLng(35.392, -81.256)
];
// Creating an array with the points for the inner polygon
var polyInner = [
new google.maps.LatLng(36.705, -80.459),
new google.maps.LatLng(36.705, -79),
new google.maps.LatLng(35.9, -79),
new google.maps.LatLng(35.9, -80.459)
];
var points = [polyOuter, polyInner];
// Creating the polygon
var polygon = new google.maps.Polygon
({
paths: points,
map: map,
strokeColor: '#ff0000',
strokeOpacity: 0.6,
strokeWeight: 3,
fillColor: '#FF0000',
fillOpacity: 0.35
});
};
})();
One of the paths has to be reverted so polygons are drawn in different directions, for example:
var polyInner = [
new google.maps.LatLng(35.9, -80.459),
new google.maps.LatLng(35.9, -79),
new google.maps.LatLng(36.705, -79),
new google.maps.LatLng(36.705, -80.459)
];
My assumption is that the reason is how SVG or canvas render closed loops. If I am not wrong explanation lies in nonzero winding rule. See explanation at wikipedia.
Outer path is drawn clockwise, inner path is drawn counter-clockwise.
Set a counter to zero. Pick a point in object area and draw a line in direction out of object space. If the line cross clockwise path, add one. If the line cross counter-clockwise path segment, subtract one. If the final result for selected point is non-zero, the browser fills the area. If the final result is zero, the browser does not fill it.
So, if you pick up point in the 'hole', the result will be zero and area will not be filled.

google maps flight path

I'm trying to create a map with a lot of flight paths, gathered from a database.
The method i use could probably be improved a little:
var flightPlanCoordinates1 = [
new google.maps.LatLng(53.63384159955519, 10.005816800985485),
new google.maps.LatLng(40.689837457540044, -74.17809198377654)
];
var flightPath1 = new google.maps.Polyline({
path: flightPlanCoordinates1,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath1.setMap(map);
...
The above will be looped over and over to show all the routes collected from the database.
So my question is, if it would be possible to simplify this, so that all of the above does not have to be looped, only the coordinates.
What i'm thinking is that a "break" function for "flightPlanCoordinates1", to break for each route, would be a good solution.
Appreciate any help
First, define your polyline options:
var pathOptions = {
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
};
Then in your loop you can create the polyline with the options:
var path = new google.maps.Polyline(pathOptions);
Then get the start and end points (where start_lat/lng end_lat/lng are your coordinates):
var start_point = new google.maps.LatLng(start_lat, start_lng);
var end_point = new google.maps.LatLng(end_lat, end_lng);
Then apply it to the polyline and set it on the map:
path.getPath().setAt(0, start_point);
path.getPath().setAt(1, end_point);
path.setMap(map);
You get the idea?

Categories