I'm writing a code that will plot multiple locations on a map using google's api. The coordinates, name and MMSI number is stored on an XML file and is imported in a javascript.
This is the part of code I'm talking about:
for(i=0; i<x; i++)
{
var locations = [
['MMSI', 50.26835, 50.45563, 1],
['MMSI', 50.29435, 50.44523, 2],
['MMSI', 50.09399, 50.40548, 3]
}
What I would like to do is add i to the end of 'MMSI' and turn it into a variable which is predefined above.
So what is written above the first code is:
var MMSI1 = 163474;
var MMSI2 = 209483;
var MMSI3 = 705245;
etc, etc...
and need the map markers to display those numbers instead of simply MMSI.
But I don't know how to achieve this as the program won't run every time I try it and google's api will only work with quotes, not variables.
I'm pretty sure there is a simple answer to this question and I am sorry for having to ask such a stupid question but I can't seem to find an answer anywhere or figure it out on my own.
Thanks in advance for any help.
Also I'm sorry if I used any terms wrong I'm still learning this language and I don't always know if I'm saying things correctly.
Ok this seems to work, I removed your ajax call to load the XML and pasted the XML in the fiddle itself. Also, I'm not an XML guru so there might be an easier method for the first part.
http://jsfiddle.net/gt8vK/4/
var x= "<Vessels><Ship><MMSI>431000527</MMSI><CALLSIGN>SLBM</CALLSIGN><LATITUDE>35.4150</LATITUDE><LONGITUDE>139.725</LONGITUDE><DESTINATION>JP SGM</DESTINATION></Ship><Ship><MMSI>244660180</MMSI><CALLSIGN>PD8027</CALLSIGN><LATITUDE>52.4066</LATITUDE><LONGITUDE>4.82345</LONGITUDE><DESTINATION>lalallal</DESTINATION></Ship></Vessels>";
var xmlDoc = new DOMParser().parseFromString(x,'text/xml');
var allShips = xmlDoc.getElementsByTagName("Ship");
console.log(xmlDoc.getElementsByTagName("Ship")[0].getElementsByTagName("MMSI")[0].childNodes[0].text)
var ships = [];
for (var i = 0, l = allShips.length; i < l; i++) {
ships.push({
name: 'MMSI' + (i + 1).toString(),
originalName: allShips[i].getElementsByTagName("MMSI")[0].childNodes[0].nodeValue,
latitude: allShips[i].getElementsByTagName("LATITUDE")[0].childNodes[0].nodeValue,
longitude: allShips[i].getElementsByTagName("LONGITUDE")[0].childNodes[0].nodeValue
})
}
var map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 2 ,
center: new google.maps.LatLng(0, 0),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < ships.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(ships[i].latitude, ships[i].longitude),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(ships[i].name);
infowindow.open(map, marker);
}
})(marker, i));
}
Basically I placed all the ships in an object, instead of creating a new variable for each one, this will keep everything cleaner and you can still access each one of them, just use ships['number'] instead of shipNumber.
Related
I've got this JS at the end of my HAML view:
:javascript
function initMap() {
var map = new google.maps.Map(document.getElementById('leadsMap')),
markers = [],
bounds = new google.maps.LatLngBounds();
- #leads.each do |lead|
- next unless lead.latitude && lead.longitude
var marker = new google.maps.Marker({
position: {lat: #{lead.latitude}, lng: #{lead.longitude}},
map: map
});
markers.push(marker);
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
map.fitBounds(bounds);
}
How can I parse the #leads so that the loop works correctly? As it stands I get a undefined local variable or method 'lead' error.
try
...
%script
- #leads.each do |lead|
- next unless lead.latitude && lead.longitude
var lead_latitude = "#{lead.latitude}";
var lead_longitude = "#{lead.longitude}";
var marker = new google.maps.Marker({
position: {lat: lead_latitude, lng: lead_longitude},
map: map
});
...
I forget if google maps api allows lat and lng in string, but you can convert lead_latitude and lead_longitude to their need (parseInt, parseDouble, etc).
if you still insist putting ruby variable inside js in haml
I'd recommend using gon 59 accomplish this if you really want to have your Ruby variables in JS.
That said, I'd strongly recommend against using script tags since ideally for security reasons you would want to block all script tags, thus preventing most forms of XSS.
Despite spending all day searching and trying numerous code methods I am still having problems with trying to center and zoom a google map correctly.
I wonder if someone would be so kind as to point out the obvious as to what Im doing wrong in my code. Everything worked fine in v2 but Im having difficulty updating to v3.
For information
The map is a small part of a much larger php application, and the needed lat & long map parameters have already been obtained by other methods which are used in the main prog and declared as follows:-
var myDestination=new google.maps.LatLng(e_lat,e_long);
var myHome=new google.maps.LatLng(h_lat,h_long);
Everything seems to be working ok aside from the zoom and center.
Problematic Code is as follows:-
function initialize()
{
// set the map properties
var mapProp = {
center:myHome,
zoom:12,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
var map=new google.maps.Map(document.getElementById("googleMap"),mapProp);
// set the home marker
var marker_home=new google.maps.Marker({
position:myHome,
icon:'house.png'
});
marker_home.setMap(map);
//set the destination marker
var marker_destination=new google.maps.Marker({
position:myDestination,
icon:'flag_red.png'
});
marker_destination.setMap(map);
//google polyline between the 2 points
var myPolyline = [myDestination,myHome];
var directPath = new google.maps.Polyline({
path:myPolyline,
strokeColor:"#0000FF",
strokeOpacity:0.8,
strokeWeight:2
});
directPath.setMap(map);
// Make an array of the LatLng's of the markers you want to show
var LatLngList = array (new google.maps.LatLng (e_lat,e_long), new google.maps.LatLng (h_lat,h_long));
// Create a new viewpoint bound
var bounds = new google.maps.LatLngBounds ();
// Go through each...
for (var i = 0, LtLgLen = LatLngList.length; i < LtLgLen; i++) {
// And increase the bounds to take this point
bounds.extend (LatLngList[i]);
}
// Fit these bounds to the map
map.fitBounds (bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);
TIA for any help :)
In your code "array" is not defined. See jsFiddle.
var LatLngList = array (new google.maps.LatLng (e_lat,e_long), new google.maps.LatLng (h_lat,h_long));
You should use
var LatLngList = new Array(new google.maps.LatLng...)
or
var LatLngList = [new google.maps.LatLng...]
I have a Google Map with a bunch of markers.
I add markers to the map one-by-one and need to remove individual markers one-by-one too when required, using individual IDs.
Currently I have some horrible, verbose code, involving a global array of markers, an ID added as metadata to each marker, and a clunky method for looking up a marker's position within the array, as follows:
var markersArray = [];
function getPositionById(markerId, arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].metadata.id === markerId) {
return i;
}
}
return null;
}
function removeMarker(markerId) {
var marker_position = getPositionById(markerId, markersArray);
if (marker_position !== null) {
markersArray[marker_position].setMap(null);
markersArray.splice(marker_position,1);
}
}
function setMarker(position, markerId) {
removeMarker(markerId);
var temp_marker = new google.maps.Marker({
position: position
});
temp_marker.setMap(map);
temp_marker.metadata = { id: markerId };
markersArray.push(temp_marker);
}
Could anyone suggest an even slightly more elegant way to do it?
Given that to remove a marker from the Map you need to use setMap(null), means that you need to have a reference to that marker.
The way you presented in your question doesn't look as horrible as you think, but another way to do it is to use a map instead of an array (not sure if map is the best term to use here since we are already working with the Google maps Map), nonetheless, using a map would rid you from the getPositionById() function, off course this assumes that all your markerIds are unique.
Your code would look something like this.
var markers = {};
function removeMarker(markerId) {
if(markers[markerId]){
markers[markerId].setMap(null);
delete markers[markerId];
}
}
function setMarker(position, markerId) {
removeMarker(markerId);
var temp_marker = new google.maps.Marker({
position: position
});
temp_marker.setMap(map);
temp_marker.metadata = { id: markerId };
markers[markerId] = temp_marker;
}
I'm trying to add markers to a google maps by iterating through a list and retrieving some information. I'm using the prototype library. The code is the following:
var point = new Array();
var myMarkerOptions = new Array();
var marker = new Array();
recommendedList.each(function(item){
point[item.location.ID] = new google.maps.LatLng(item.location.lat, item.location.lng);
myMarkerOptions[item.location.ID] = {
position: point[item.location.ID],
map: map
};
marker[item.location.ID] = new google.maps.Marker(myMarkerOption[item.location.ID]);
});
where the recommendedList is a JSON response of the form:
[
{"artist":"artist1","location":{"lat":"50.952226","lng":"5.34832","ID":28}},
{"artist":"artist2","location":{"lat":"52.362287","lng":"4.883965","ID":32}},
...
]
However, this is not working.
I know that the problem is not about the JSON or the google map, because I tried a simpler version with the following code and it worked:
var myLatlng = new google.maps.LatLng(recommendedList[0].location.lat,recommendedList[0].location.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map
});
So the problem must be in the iteration and the hash maps.
Anyone can see the problem? Thanks!
Simple enough to test without the .each
for (var i=0, item; item = recommendedList[i]; i++) {
point[item.location.ID] = new google.maps.LatLng(item.location.lat, item.location.lng);
myMarkerOptions[item.location.ID] = {
position: point[item.location.ID],
map: map
};
marker[item.location.ID] = new google.maps.Marker(myMarkerOption[item.location.ID]);
}
You can also simplify this quite a lot, unless you "need" those other arrays:
for (var i=0, item; item = recommendedList[i]; i++) {
marker[item.location.ID] = new google.maps.Marker({
new google.maps.LatLng(item.location.lat, item.location.lng),
map
});
}
I think it could be the array accessors you're using. What are you doing the point, myMarkerOptions and marker arrays once you're done with them?
Can you try declaring them as
var point = {};
var myMarkerOptions = {};
var marker = {};
That'll let you refer to them as point[item.location.ID] (etc). I think with the item.ID property being a number, JS is trying to set that numeric index of the array, rather than creating a new property in your hash.
Prototype each iterator doesn't support JSON or object data type.
I have a google maps api function place markers which I'm using from the tutorial found here:Google Maps API with JQuery
By any means, I had to modify the javascript to account for my application. I'm pulling markers from an XML file like before, though this time I'm getting multiple requests, and multiple standard deviation, time to serve, and means for these requests. I've set up the XML to have these with a counter appended to the tag, but it looks like it's not rendering into an array correctly.
To note, I've never used Javascript, and am mostly flying by the seat of my pants on this, so if it's an atrocity of Javascript, feel free to let me know, the entire generation of the XML is in Python.
Sample of the XML: (I apologize, I don't know how to show < or > on stack overflow without it simply hiding it as a tag. Around each "markers" "marker" "name" "requestX" "timetoserveX" etc. is the < and > for tags in XML.
markers
marker
name Simpletown, CA /name
request0 /resource/ /request0
timetoserve0 .001 Seconds to serve request /timetoserve0
mean0 .5309 Mean in seconds /mean0
std_dev0 .552 Standard Deviation in Seconds /std_dev0
request1 /resource2/ /request1
timetoserve1 0.015626 Seconds to serve request /timetoserve1
mean1 0.0011 Mean in seconds /mean1
std_dev1 0.004465 Standard Deviation in Seconds /std_dev1
/marker
/markers
MYMAP.placeMarkers = function(filename) {
$.get(filename, function(xml){
$(xml).find("marker").each(function(){
var name = $(this).find('name').text();
var count = 0;
var requeststring = 'request' + Integer.toString(count)
var request = new Array();
var timetoserve = new Array();
var mean = new Array();
var std_dev = new Array();
var timetoservestring = 'timetoserve' + Integer.toString(count);
var meanstring = 'mean' + Integer.toString(count);
var std_devstring = 'std_dev' + Integer.toString(count);
while ($(this).find(requeststring).text()){
timetoservestring = 'timetoserve' + Integer.toString(count);
meanstring = 'mean' + Integer.toString(count);
std_devstring = 'std_dev' + Integer.toString(count);
request[count] = $(this).find(requeststring).text();
timetoserve[count] = $(this).find(timetoservestring).text();
mean[count] = $(this).find(meanstring).text();
std_dev[count] = $(this).find(std_devstring).text();
count++;
requeststring = 'request' + Integer.toString(count)
}
// create a new LatLng point for the marker
var lat = $(this).find('lat').text();
var lng = $(this).find('lng').text();
var point = new google.maps.LatLng(parseFloat(lat),parseFloat(lng));
// extend the bounds to include the new point
MYMAP.bounds.extend(point);
var marker = new google.maps.Marker({
position: point,
map: MYMAP.map
});
var infoWindow = new google.maps.InfoWindow();
var html = ""
for (i=0;i<count;i++){
html=html+'<strong>'+name+'</strong.><br />'+request[i]+'<br />'+timetoserve[i]+'<br />'+mean[i]+'<br />'+std_dev[i]+<br />;
//var html='<strong>'+name+'</strong.><br />'+request+'</strong.><br />'+timetoserve+'</strong.><br />'+mean+'</strong.><br />'+std_dev;
}
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent(html);
infoWindow.open(MYMAP.map, marker);
});
MYMAP.map.fitBounds(MYMAP.bounds);
});
});
}
With the updates, it's not longer having the array issues it looks like, even though I am getting the map to render at this point. The "Show Markers" button is not populating the map with markers. Running FireBug with this seems to only spew endless amounts of "Break on error" hits and warnings for jQuery.
var request[count] = $(this).find(requeststring).text();
var timetoserve[count] = $(this).find(timetoservestring).text();
var mean[count] = $(this).find(meanstring).text();
var std_dev[count] = $(this).find(std_devstring).text();
to
request[count] = $(this).find(requeststring).text();
timetoserve[count] = $(this).find(timetoservestring).text();
mean[count] = $(this).find(meanstring).text();
std_dev[count] = $(this).find(std_devstring).text();
-assuming these are the arrays that are not working correctly for you.
If I may make a suggestion (RE your comment this morning):
while ($(this).find(requeststring).text()){
//...omitted
}
if you were to rename all your tags to the same thing and give them an id attribute (which is valid in xml) you can do this:
var requests = $(this).find('request');
var timetoserves = $(this).find('timetoserve');
// etc...
for (var i=0; i<requests.length; i++) {
request[i] = requests.eq(i).text();
timetoserve[count] = timetoserves.eq(i).text();
//etc...
}
which would probably provide better performance.