Once I have created a map with multiple markers using google maps API, I want to additional selections to highlight a subset of markers displayed. I would like to do this without going back to the server. Preferably I would like to store data in marker or array. I could either substitute with new marker or overlay an image on top of the marker. Can anyone propose example of how to do this - specifically part about adding image or change marker.
Example below...
Here's an example, which assumes that when you load your page you have this data returned from the server in JSON.
data = [{
latitude: 103.2,
longitude: 12.3,
isDiscountOutlet: false
}, {
latitude: 101.2,
longitude: 11.3,
isDiscountOutlet: false
}
]
The basic approach is that we store that data in the browser, and use it to update the appearance of markers when changing a selection.
Part 1: Create a global variable to store our markers in
var storedMarkers;
Part 2: Create a Map using the data from the server
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(103, 11)
}
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// Add the markers. We are going to store them in a global array too,
// so we can access them later.
for (var i = 0; i < data.length; ++i) {
// Create one marker for each piece of data.
var marker = new google.maps.Marker({
position: new google.maps.LatLng(data[i].latitude, data[i].longitude),
map: map
});
// Store that marker, alongside that data.
var dataToStore = {
markerObject: marker,
dataAssociatedWithMarker: data[i]
};
storedMarkers.push(dataToStore);
}
google.maps.event.addDomListener(window, 'load', initialize);
Part 3: Let's show all discount outlets, and hide all other markers, when someone clicks a button
I'm assuming you have a DOM element (a button) with id 'discount'. I'm also going to cheat and use jQuery :)
$("#discount").click(function () {
for (var i = 0; i < storedMarkers.length; ++i) {
var currentStoredMarker = storedMarkers[i];
// Is this marker a discount outlet?
if (currentStoredMarker.dataAssociatedWithMarker.isDiscountOutlet == true) {
// Let's show it!
currentStoredMarker.markerObject.setVisible(true);
} else {
// Let's hide it!
currentStoredMarker.markerObject.setVisible(false);
}
}
});
Related
Im trying to change the mapview while using Bing maps API. I have my map initialized already but im trying to change the map view to center in on a pin who's location i have. Im merely trying to get the view to move using setView but im unsure how to move it.
function findpin() {
console.log("hello3");
var pin;
//loop through and find searched pin object
for (var i = 0; i < allPins.length; i++) {
if (searchbox.value == allPins[i].entity.title) {
pin = allPins[i];
break;
}
};
console.log(pin);
//set pin
pinSelected(pin);
//var locs = [array of Microsoft.Maps.Location];
//var rect = Microsoft.Maps.LocationRect.fromLocations(locs);
map = setView({
mapTypeId: Microsoft.Maps.MapTypeId.aerial,
center:new Microsoft.Maps.Location(0, 0),
zoom:100,
});
console.log("hello5");
}
Assuming that you initialized the map by:
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {});
Then you can use the setView on the instantiated map to update the view:
map.setView({
mapTypeId: Microsoft.Maps.MapTypeId.aerial,
center: new Microsoft.Maps.Location(0, 0),
zoom: 20
});
Notice that the max zoom level is 20.
I'm trying to measure the distance between a marker and a point that has been searched for by postcode. The idea is to make markers appear within a certain radius. as far as I can tell I've done it right but clearly not.
The current code for the function looks like this:
function setup_map(latitude, longitude) {
var _position = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
zoom: 14,
center: _position
}
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
#foreach (var i in ViewData.Model)
{
<text>
var markerPos = {lat: #i.Lat, lng:#i.Long}
var distance = google.maps.geometry.spherical.computeDistanceBetween(markerPos, _position);
var marker = new google.maps.Marker
({
position: new google.maps.LatLng (markerPos),
map: map,
title: "" + (#i.id),
});
</text>
}
}
This function reloads the map and all the markers on it. At the minute I'm not too concerned with loading the markers within the radius. I just want to load them all.
When you click the search button, the map loads to the postcode entered but doesn't load any markers. If I remove the "var distance" line, it still goes to the postcode and loads all of the markers. So by process of elimination, there must be something wrong with this line but I have no idea what.
I have a database which stores the position of markers previously added on the Google Map (Latitude/Longitude). What I want to do now, it's to create a function which takes a JSON object as a parameter, containing those markers position and add automatically the markers in the map. I start to get the markers from my database and try to loop on the JSON object which looks like this:
{"markers":"\"[{\\\"k\\\":48.80686346108517,\\\"B\\\":1.494140625},{\\\"k\\\":50.28933925329177,\\\"B\\\":14.326171875},{\\\"k\\\":43.70759350405294,\\\"B\\\":21.357421875},{\\\"k\\\":30.977609093348686,\\\"B\\\":11.337890625},{\\\"k\\\":40.58058466412761,\\\"B\\\":-0.87890625},{\\\"k\\\":48.45835188280866,\\\"B\\\":1.318359375}]\""}
Here is the current state of my code:
//Create a new set of markers based on received position.
function createMarkerBasedOnFetchedPosition(fetchedMarkersPosition)
{
var jsonData = JSON.parse(fetchedMarkersPosition);
alert(fetchedMarkersPosition);
map.addMarker({
lat: ? //Fetched from the JSON object parsing.
lng: ? //Fetched from the JSON object parsing.
animation: google.maps.Animation.DROP
});
Can anyone please help me to build this, I don't know yet how to deal with a JSON object to retrieve the Latitude/Longitude. I'm looking for a JavaScript solution only. Thanks for your help!
From your current code you would then need to loop through the markers with a for loop like so and add a marker to the map:
var data = '{"markers":[{"k":48.80686346108517,"B":1.494140625},{"k":50.28933925329177,"B":14.326171875},{"k":43.70759350405294,"B":21.357421875},{"k":30.977609093348686,"B":11.337890625},{"k":40.58058466412761,"B":-0.87890625},{"k":48.45835188280866,"B":1.318359375}]}';
function createMarkerBasedOnFetchedPosition(fetchedMarkersPosition)
{
var jsonData = JSON.parse(fetchedMarkersPosition);
for (var i = 0; i < jsonData.markers.length; i++) {
map.addMarker({
lat: jsonData.markers[i].k,
lng: jsonData.markers[i].b,
animation: google.maps.Animation.DROP
});
}
}
createMarkerBasedOnFetchedPosition(data);
I am new to Google maps, I am plotting the gps data onto a Google map, it works fine up to 500 points. If the data exceeds more than 500 it slows down is there any alternate way to plot markers onto a map.
I am just marking the gps data in Google map on certain time period.
Later I need to plot hundreds of thousands of gps data in Google map,below method slows down and exit the firefox or chrome (it times out).
How to plot more data on google map and also it should be fast
My javascript code, sale data will be of json data:
function show_map_all_data(sale_data)
{
init_map();
var count_actual=sale_data.length;
var locations=[];
for (var i=0;i<count_actual;i++)
{
var temp=[]
temp.push(sale_data[i]['GPS_latitude'],sale_data[i]['GPS_longitude'])
locations.push(temp);
}
//console.log(locations);
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][0], locations[i][1]),
icon: {
path: google.maps.SymbolPath.CIRCLE,
strokeColor: '#8e2014',
scale: 4,
strokeOpacity: 1.0,
strokeWeight: 10,
fillColor: '#8e2014',
animation: google.maps.Animation.DROP,
},
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0] + "," + locations[i][1]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
You'll likely need to look into markerclustering in order to speed up your page load times (and avoid time out). Multiple markers rendered on the client side is probably the downfall of many mapping applications performance wise. It is difficult to benchmark, fix and in some cases even establish there is an issue (due to browser implementation differences, hardware available to the client, mobile devices, the list goes on).
The simplest way to begin to address this issue is to use a marker clustering solution. The basic idea is to group geographically similar locations into a group with the number of points displayed. As the user zooms into the map these groups expand to reveal individual markers beneath.
Perhaps the simplest to implement is the markerclusterer library. A basic implementation would be as follows (after library imports, and not reflective of your code, this is just the simplest example I could come up with):
<script type="text/javascript">
function initialize() {
var center = new google.maps.LatLng(37.4419, -122.1419);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var markers = [];
for (var i = 0; i < 100; i++) {
var location = yourData.location[i];
var latLng = new google.maps.LatLng(location.latitude,
location.longitude);
var marker = new google.maps.Marker({
position: latLng
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
The markers instead of being added directly to the map are added to an array. This array is then passed to the library which handles complex calculation for you and attached to the map.
Not only do these implementations massively increase client side performance but they also in many cases lead to a simpler and less cluttered UI and easier digestion of data on larger scales.
Other implementations are available from Google.
Edit to answer comment
If you look here: http://gmaps-utility-library.googlecode.com/svn/trunk/markerclusterer/1.0/docs/reference.html and look for a property called maxZoom you can set a zoom level in the clusterer options object after which the clustering will be turned off to allow all markers to be plotted.
I'd like to know how to put multiple markers for Google Maps using Javascript API v3.
I tried the solution posted here, but it does not work for me for some reason:
var directionDisplay;
function initialize() {
var myOptions = { zoom: 9, center: new google.maps.LatLng(40.81940575,-73.95647955), mapTypeId: google.maps.MapTypeId.TERRAIN }
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
setMarkers(map, properties);
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'],
];
function setMarkers(map, buildings) {
var image = new google.maps.MarkerImage('map_marker.png', new google.maps.Size(19,32), new google.maps.Point(0,0), new google.maps.Point(10,32));
var shadow = new google.maps.MarkerImage('map_marker_shadow.png', new google.maps.Size(28,32), new google.maps.Point(0,0), new google.maps.Point(10,32));
var bounds = new google.maps.LatLngBounds;
for (var i in buildings) {
var myLatLng = new google.maps.LatLng(buildings[i][1], buildings[i][2]);
bounds.extend(myLatLng);
var marker = new google.maps.Marker({ position: myLatLng, map: map, shadow: shadow, icon: image, title: buildings[i][0] });
google.maps.event.addListener(marker, 'click', function() { window.location = ('detail?b=' + buildings[i][3]); });
}
map.fitBounds(bounds);
}
}
</script>
Could anyone kindly explain why this doesn't work for me?
This question is already a few months old, but I noticed that it remained unanswered. I guess the OP already found a way through this, but let me attempt an answer for the sake of completeness.
I can spot a few major problems in your code above:
First of all, you are trying to pass the properties array to the setMarkers() function, before properties is defined. Therefore setMarkers() will receive undefined for the second argument, which is why nothing is showing on your map.
Then, you are having a very common closure problem in that for in loop. Variables enclosed in a closure share the same single environment, so by the time the click callback from the addListener is called, the loop will have run its course and the i variable will be left pointing to the last value it had when loop ended.
In addition, you have a dangling comma in the array literal, which can cause a syntax error in some browsers.
To fix the first problem, simply define the properties array before calling setMarkers():
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'],
];
setMarkers(map, properties);
You can then solve the closure problem with even more closures, using a function factory:
function makeClickCallback(buildings, i) {
return function() {
window.location = ('detail?b=' + buildings[i][3]);
};
}
for (var i in buildings) {
// ...
google.maps.event.addListener(marker, 'click',
makeClickCallback(buildings, i);
}
This can be quite a tricky topic, if you are not familiar with how closures work. You may to check out the following Mozilla article for a brief introduction:
Working with Closures
Then you may want to make sure to remove the dangling comma in your array literal:
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'] // no comma
];
In addition, note that since there is just one element in your properties array, you will only get one marker on the map. I'm not sure if the other elements were removed for the sake of this example, but if it wasn't, simply add more locations like this:
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'],
['Another Location',50.505050,-75.505050,'Mjg5']
];