I'm new to javascript and to programming itself, I'm trying to add markers in google maps api and load it's coords from mysql, I have everything done but now I got stuck into something, is it possible to create a number of variables based on the number of coords I have ? here is what I have:
function get_values(numero, array)
{
var i;
for(i=0;i<numero;i++)
{
//var i ( HERE: i want it to set variables based on i )= new google.maps.Marker({
position: array[2],
//map: map,
//title:"Hello World!"
});
}
}
It appears what you need to use is an array. This will allow you to store as many coordinates as you want and you'll be able to access them by index (number). For example, if you have 10 coordinates, they could be stored in an array like:
position[i] = array[2]
Your code looks, though, pretty broken, so I think you need more help getting started than what pointed questions on Stack Overflow will get you.
As Gordon says you need an array. If I understand correctly you want to create one marker for each iteration ?
Then I guess something like this would do the trick :
function get_values(numero, array)
{
var i;
var markers = new Array(numero); // create an array to store the markers
for(i=0;i<numero;i++)
{
markers[i] = new google.maps.Marker({
position: array[i],
map: map,
title: "Hello marker " + i // give a different title to each marker based on the number..
});
}
return markers;
}
This assumes that your get_values function takes the number of positions and an array of positions as parameters.
Related
I'm working on a dynamic map API which you can set as you like to. After a person puts in the name of his place I can get the viewport latitude and longitude. First of all, I get 2 values and second they are are both off according to the real coordinates. I see the result back to my own map API as well.
After much confusing I started to compare the 2 and divide them. This still gives a wrong integer.
With this I get the values which are coupled to the name that has been given.
google.maps.event.addDomListener(searchBox, 'places_changed', function(event) {
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for (i = 0; place = places[i]; i++) {
bounds.extend(place.geometry.location);
marker.setPosition(place.geometry.location);
for(key in places) {
if(places.hasOwnProperty(key)) {
var value = places[key];
var geoLong = value.geometry.viewport.b.b;
var geoLat = value.geometry.viewport.f.f;
Example:
Empire State builiding: Real coordinates: 40.748817, -73.985428.
My results: latitude: 40.746983 and 40.749681 : longitude -73.983858 and -73.986556.
This is from geometry.viewport.b.(b or f) and geometry.viewport.f.(b or f) That's how I retrieved the information.
Possible solution:
After much try and error of getting the right results, I stumbled onto this.
google.maps.event.addListener(map, 'click', function(event){
console.log( "Latitude: "+event.latLng.lat()+" "+", longitude: "+event.latLng.lng() );
});
While this is giving the right value back I can't call it like I did with the other 2. It keeps saying that latLng is undefined and that is true because it doesn't work with the objects/array which is given by places.
Question: How come that the viewport is giving a different value then the real coordinates?
If I understand correctly, your intention is to get the position of the place from Google database.
I would suggest following the official API reference documentation and avoid using things like viewport.b.b or viewport.f.f in your code. Note that once Google updates the version of the API these undocumented properties might change their names.
If you check the documentation you will see that getPlaces() method of search box returns an Array<PlaceResult> result.
https://developers.google.com/maps/documentation/javascript/reference#SearchBox
So, var value in your code has type PlaceResult that is documented here:
https://developers.google.com/maps/documentation/javascript/reference#PlaceResult
The geometry property of place result has a PlaceGeometry type that is documented here:
https://developers.google.com/maps/documentation/javascript/reference#PlaceGeometry
That means that in order to get position of the place you should execute the following code
var value = places[key];
var geoLong = value.geometry.location.lng();
var geoLat = value.geometry.location.lat();
I hope this helps!
I created a prototype for a project I'm working on, in which the user should create various markers in a map, be able to remove them, calculate a route with the markers, and go back to manage the markers.
I used some code found here in geocodezip.com to calculate the route, and wrote some for the markers, etc.
My problem is that once the user calculates the route, no matter how he edits the markers, when clicking the button to calculate the route, the map only returns the route with the markers that were there on the first time he clicked the button. And the strangest thing is that I checked the coordinates that are being passed to the script that generates the route and the function is sending the markers as it should, but no matter the coordinates sent, it only works correctly on the first time.
Js Fiddle: https://jsfiddle.net/1kmg2u65/2/
The code is really really long so it's all in the Fiddle, but this is what it does:
1. User clicks on map, generate marker, marker goes to an array
2. If user deletes marker, it becomes null in array, to maintain the indexes
3. 'Clean' markers array receives all the markers in order, without the items that are null
4. A function is called with all the markers, this function creates the route
5. To manage the markers, a function reload the map just like it was in the start, but render all the markers that already are in the markers array
it works fine if you remove the conditional if (!window.tour) in Tour_startUp function definition.
So here is what I believe is going on.
In the function markMap() you are instantiating new markers that belong to the google map object.
for (var i = 0; i < markerElements.length; i++){ //Loop para gerar os marcadores
if (markerElements[i] != null){
marker = new google.maps.Marker({
position: markerElements[i].position,
map: map,
title: markerElements[i].title
});
}
}
This if fine, but you are not storing that constructed object anywhere. You need to be able to reference that marker to UN-associate it from the map.
At the end of the this for loop you need to add THAT mark to a global array so you can manage it later in the script.
EXAMPLE
// defined at the top of the script
var markerGlobal = [];
for (var i = 0; i < markerElements.length; i++){ //Loop para gerar os marcadores
if (markerElements[i] != null){
marker = new google.maps.Marker({
position: markerElements[i].position,
map: map,
title: markerElements[i].title
});
// push marker onto global array
markerGlobal.push(marker);
}
}
Now we can loop through the array and setMap to null
// un-reference marker from map
markerGlobal[2].setMap(null);
I see you tried to do this with the removeMarker() function, but it doesn't have the handles to the markers already added to the map.
Some Suggestions
If I was you, I would think about refactoring the code to have one multi dimensional object that holds all the markers, their row info, variables etc.
You could take it one step further and create a constructor function that handles the map and its associated markers. It would be most efficient.
Good luck.
I am using google maps api v3, and i need to move many(hundreds) of markers at the same time. From server, i get array of objects, representing a marker with it´s coordinates as it moved over time(few months), ordered by time when it moved. Above my map, i have a progress bar representing time with "month:year" text. What my code does, is move the marker(and draw polyline) at the exact time so it fits the time currently displayed on the "time progress bar". At every position where the marker stops, i leave a new marker to show the history of the movement. The whole process repeats over and over(setInterval() function). My code is working, the problem is performance, so i am asking: is there any way i could improve the performance ? some better way than i am doing it? there must be something. Here is my code:
if (mapOverTime != null) {
trackables.forEach(function (trackable) {
var marker = new google.maps.Marker({
map: mapOverTime,
draggable: false,
clickable: false,
icon: geoIcon,
animation: google.maps.Animation.none,
zIndex: 2
});
var polyline = new google.maps.Polyline(polyOptions);
polyline.setMap(mapOverTime);
// adding these to arrays so i can access and remove them from the map later
markersArray.push(marker);
polylineArray.push(polyline);
trackable.years.forEach(function(year) {
$.each(year.months, function(index, month) {
setTimeout(function() {
if (month.coordinates.length > 0) {
var moveCounter = month.coordinates.length;
var timeToMove = Math.floor(pause_interval / moveCounter);
$.each(month.coordinates, function(i, position) {
var latTo = position.latitude;
var lngTo = position.longitude;
var destination = new google.maps.LatLng(latTo, lngTo);
setTimeout(function() {
moveToPosition(marker, destination, polyline);
}, (i) * timeToMove);
});
}
}, pause_interval * index);
});
});
});
}
This is the function making the moves happen:
function moveToPosition(marker, destination, polyline) {
// current path of the polyline
var path = polyline.getPath();
// add new coordinate
path.push(destination);
// rendering whole line would make the map even more chaotic, this makes the line dissapear after 8 moves of the marker
if (path.getLength() > 8) // comment out to render whole
th.removeAt(0); // path of polyline
// set marker position to the new one
marker.setPosition(destination);
// render new marker on this position so that it is well visible where the coins were
var historyPoint = new google.maps.Marker({
map: mapOverTime,
draggable: false,
icon: historyIcon,
animation: google.maps.Animation.none,
zIndex: 0
});
historyPoint.setPosition(destination);
// again add to global array so i can set access and remove this marker from the map later
historyPoints.push(historyPoint);
}
The only thing i do, is iterate through all the markers and it´s coordinates, move marker at given time, draw line behind it, create new marker at the new position, and go for another coordinates. When 1 iteration end, all the objects are removed from the map and the process starts again. Any idea how to improve performance? or the only solution is to decrease the number of markers i want to render? Thank you for your opinions!
Suggestions:
Why bother specifying animation: google.maps.Animation.none,? If you're not using it, just remove it. And according to the docs, there are two values, BOUNCE and DROP, so there isn't a none value anyway.
Use standard javascript array looping, instead of jquery's $.each() if you can; it's faster
You create two variables just for the benefit of specifying your destination coordinates. You use them once, and never again, so why not just use the original values? i.e.
var latTo = position.latitude;
var lngTo = position.longitude;
var destination = new google.maps.LatLng(latTo, lngTo);
just becomes
var destination = new google.maps.LatLng(position.latitude, position.longitude);
Another improvement you could make here. Use the shorthand inline struct notation for specifying your destination coordinates. It should reduce some overhead in creating hundreds of LatLng objects. i.e.
var destination = new google.maps.LatLng(position.latitude, position.longitude);
then becomes:
var destination = {lat: position.latitude, lng: position.longitude};
You create a polyline, then you set the map:
var polyline = new google.maps.Polyline(polyOptions);
polyline.setMap(mapOverTime);
I see this all the time and never understand it... just add map: mapOverTime to the polyOptions, saves having to do an additional function call.
Similarly with historyPoint... don't call setPosition() on it, just specify position: destination in the options you pass when you create the marker
All these are minor things which will likely make little different to trying to move hundreds of markers at once, but I'd still recommend you try them anyway.
I currently have a set of nicely declared array of latitude/longitude points using javascript and mySQL and when I used this set of arrays to show as polylines it was successful.
var polyline= L.polyline(xxx).addTo(map);
However when I tired to change to markers, the map did not portrayed any markers.
Any help? Much appreciated :)
That's because L.Polyline, takes a nested array of multiple lat/lng coordinates as the first parameter, L.Marker takes a single array with lat/lng coordinates. The signature is different:
L.Polyline:
new L.Polyline([[-45, -45], [45, 45]], {/*options*/});
L.Marker:
new Marker([-45, -45], {/*options*/});
When you pass a nested array to L.Marker, like the one shown above in the polyline, it throws an error:
Uncaught TypeError: Cannot read property 'lat' of null
If you want to use the set of coordinates of the polyline to show markers at the start and/or endpoint of the line you could do this:
var coordinates = [[-45, -45], [45, 45]];
var startMarker = new Marker(coordinates[0], {/*options*/});
var endMarker = new Marker(coordinates[1], {/*options*/});
As promised in the comments another easier way to add markers from a large array:
var coordinates = [
[-41.31825,174.80768],
[-41.31606,174.80774],
[-41.31581,174.80777],
[-41.31115,174.80827],
[-41.30928,174.80835],
[-41.29127,174.83841],
[-41.33571,174.84846],
[-41.34268,174.82877]
];
coordinates.forEach(function (coordinate) {
new L.Marker(coordinate).addTo(map);
});
Much easier than doing:
new L.Marker(coordinate[0]).addTo(map);
new L.Marker(coordinate[1]).addTo(map);
new L.Marker(coordinate[2]).addTo(map);
new L.Marker(coordinate[3]).addTo(map);
new L.Marker(coordinate[4]).addTo(map);
new L.Marker(coordinate[5]).addTo(map);
new L.Marker(coordinate[6]).addTo(map);
new L.Marker(coordinate[7]).addTo(map);
Working example on Plunker: http://plnkr.co/edit/3dbJgb?p=preview
I was helped out by an SO member with the following code which allows me to use multiple markers from a PHP array and plot them on a map:
for (i = 0; i < locations.length; i++)
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][0], locations[i][1]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function()
{
infowindow.setContent(locations[i][2]);
infowindow.open(map, marker);
}
})(marker, i));
}
So that code is grabbing my array and putting my markers on the map and in the infowindow, printing out the customer name.
I quickly came across an issue however. If a customer share's the same lat/long (they're derived from postcode), only one of the customers appear - e.g. Customer1 at LN1 7HQ and Customer2 at LN1 7HQ, only customer 1 will appear in the info window.
A few solutions I found include clustering markers and offsetting them - but what I would like is the have 1 infowindow for each postcode and then list the customers located there in the window.
I haven't found a way to do it but would assume it will involve altering the For loop below and adding something like "If lat, long === lat, long, then locations[i][2] ++ ..." but I'm just about grasping PHP and javascript is still new to me.
Any help would be much appreciated.
One possible solution: track created markers using array
var markers = [];
with information about location indexes using following object:
function MarkerInfo(marker, idx) {
this.marker = marker;
this.locations = [idx];
}
There are two loops. The 1st loop build array of MarkerInfo with marker and list of indexes from locations array. The 2nd loop prepares content string for infowindow and creates listeners.
See example at jsbin.
Note: for the future changes: solution won't work properly if you change locations array with information about customers between those two loops.