I'm currently working on an application where various markers are placed with infowindows on a Google Map based on a user's posts. I've also included geocoding so that the user can change their location and view markers/posts in any area.
What I'd like to do is for the user to search through the text info in the infowindows via a form and the map then responds by showing the markers that contain that text window. I've searched through the API and I don't see this ability mentioned, although it seems like it should be achievable.
Any insight or information on how to accomplish this would be much appreciated.
Here's the current code within the application:
function mainGeo()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition( mainMap, error, {maximumAge: 30000, timeout: 10000, enableHighAccuracy: true} );
}
else
{
alert("Sorry, but it looks like your browser does not support geolocation.");
}
}
var stories = {{storyJson|safe}};
var geocoder;
var map;
function loadMarkers(stories){
for (i=0;i<stories.length;i++) {
var story = stories[i];
(function(story) {
var pinColor = "69f2ff";
var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=S|" + pinColor,
new google.maps.Size(21, 34),
new google.maps.Point(0,0),
new google.maps.Point(10, 34));
var point = new google.maps.LatLng(story.latitude, story.longitude);
var marker = new google.maps.Marker({position: point, map: map, icon: pinImage});
var infowindow = new google.maps.InfoWindow({
content: '<div >'+
'<div >'+
'</div>'+
'<h2 class="firstHeading">'+story.headline+'</h2>'+
'<div>'+
'<p>'+story.author+'</p>'+
'<p>'+story.city+'</p>'+
'<p>'+story.topic+'</p>'+
'<p>'+story.date+'</p>'+
'<p>'+story.copy+'</p>'+
'<p><a href='+story.url+'>Click to read story</a></p>'+
'</div>'+
'</div>'
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,this);
});
})(story);
}
}
function mainMap(position)
{
geocoder = new google.maps.Geocoder();
// Define the coordinates as a Google Maps LatLng Object
var coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
// Prepare the map options
var mapOptions =
{
zoom: 15,
center: coords,
mapTypeControl: false,
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Create the map, and place it in the map_canvas div
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// Place the initial marker
var marker = new google.maps.Marker({
position: coords,
map: map,
title: "Your current location!"
});
loadMarkers(stories);
}
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function error() {
alert("You have refused to display your location. You will not be able to submit stories.");
}
mainGeo();
Create three empty arrays (e.g., markers, infowindows, and matches)
As you instantiate the marker, reference the marker via an index in the markers array (e.g., markers[i] = marker)
As you instantiate the infowindow, reference it's content via an index in the infowindows array (e.g., infowindows[i] = htmltext [or whatever variable name you store your content in)
Search for the string in the infowindows array, store the indexes of the items that contain the string in the matches array, and then use a for loop with the matches array to add the markers from the markers array (based on the index values of the matches array).
Related
First thing is I will tell you I am new to google maps and some of it is very confusing to me. What I need to do is show a users location and have the appropriate markers show up. I have the database all ready and somewhat of the Google map.
What I am working with is an example from here. What I can either get is the markers if I use a static LatLng or just the users dynamic location with no markers.
Need help please. And if you downvote this post please let me know why.
Code I am using can be found at https://jsfiddle.net/8q1apmdy/9/ and show where in the blow code is where I am missing something, most likely small or in the wrong position.
function initMap() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
});
var map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 12
});
}
a) While running your code locally, I was getting 'pos' undefined, so I moved the following code 'var map = new google.maps.Map(..' inside the getCurrentPosition(){...
b) Then I got another error ' InvalidValueError: setMap: not an instance of Map;' so created a 'var map' globally.
Loaded the map successfully, but still markers were not loaded. while debugging your code at this point 'var marker = new google.maps.Marker({...' it is iterating for all markers from xml but somehow markers are not adding to the map..dont know the reason yet?
So I have tried in a different way. Please see all markers from xml displayed on map. Here I am just getting the 'name' in marker, you might need to add other parameters like id, address etc.
JSFiddle added for reference
var infowindow;
var map;
//var downloadUrl;
function initialize() {
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(-33.868820, 151.209290),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map'), mapOptions);
downloadUrl("https://storage.googleapis.com/mapsdevsite/json/mapmarkers2.xml", function(data) {
var bounds = new google.maps.LatLngBounds();
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName('marker');
for (var i = 0; i < markers.length; i++) {
var id = markers[i].getAttribute('id');
var address = markers[i].getAttribute('address');
var type = markers[i].getAttribute('type');
var latlng = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
bounds.extend(latlng);
var marker = createMarker(id, markers[i].getAttribute("name"), address, latlng, type);
}//finish loop
//map.fitBounds(bounds);
}); //end downloadurl
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
}
function createMarker(id, name, address, latlng, type) {
var marker = new google.maps.Marker({
position: latlng,
map: map
});
google.maps.event.addListener(marker, "click", function() {
if (infowindow) infowindow.close();
infowindow = new google.maps.InfoWindow({content: name});
infowindow.open(map, marker);
});
return marker;
}
JSFiddle
I have an application where I'm using the Google Map API to display markers for posts made by users using their lat/lon. I employed the MarkerClusterer capability for better organization of the markers, which works but with a bug of sorts.
Essentially, I've been testing this at home so the lat/lon has been the same for all test posts. Before using MarkerClusterer, zooming far into the map would eventually reveal all the markers. Unfortunately, using the MarkerClusterer, if there is, for example, a "5" listed for the number of markers that are very close together such as these test posts, clicking on the cluster reveals nothing. No markers ever appear when these are very close together. To reiterate, these markers do appear without the MarkerClusterer.
I upgraded to MarkerClustererPlus v2.0.9 per another post that described other issues with the MarkerClusterer but that hasn't solved the problem.
Any insight into this issue would be greatly appreciated.
Edit: geocodezip suggested the overlappingmarkerspidifier, which sounds great, but my code is fairly involved and I'm not sure how to incorporate it. Any insight much appreciated. Code follows:
function mainGeo()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition( mainMap, error, {maximumAge: 30000, timeout: 10000, enableHighAccuracy: true} );
}
else
{
alert("Sorry, but it looks like your browser does not support geolocation.");
}
}
var stories = {{storyJson|safe}};
var geocoder;
var map;
var markers = [];
function loadMarkers(stories){
for (i=0;i<stories.length;i++) {
var story = stories[i];
if (story.copy.length > 120) {
story.copy = story.copy.substring(0, 120) + "...";
}
(function(story) {
var pinColor = "69f2ff";
var pinImage = new google.maps.MarkerImage("http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=S|" + pinColor,
new google.maps.Size(21, 34),
new google.maps.Point(0,0),
new google.maps.Point(10, 34));
var point = new google.maps.LatLng(story.latitude, story.longitude);
var marker = new google.maps.Marker({position: point, map: map, icon: pinImage});
var infowindow = new google.maps.InfoWindow({
content: '<div >'+
'<div >'+
'</div>'+
'<h2 class="firstHeading">'+story.headline+'</h2>'+
'<div>'+
'<span>'+story.author+'</span><br />'+
'<span>'+story.city+'</span><br />'+
'<span>'+story.topic+'</span><br />'+
'<p>'+story.date+'</p>'+
'<p>'+story.copy+'</p>'+
'<p><a href='+story.url+'>Click to read story</a></p>'+
'</div>'+
'</div>'
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,this);
});
markers.push(marker);
})(story);
}
}
function mainMap(position)
{
geocoder = new google.maps.Geocoder();
// Define the coordinates as a Google Maps LatLng Object
var coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var width = window.innerWidth - 80;
size = width;
// Prepare the map options
var mapOptions =
{
zoom: 15,
center: coords,
mapTypeControl: false,
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Create the map, and place it in the map_canvas div
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
// Place the initial marker
var marker = new google.maps.Marker({
position: coords,
map: map,
title: "Your current location!"
});
loadMarkers(stories);
var markerCluster = new MarkerClusterer(map, markers);
}
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function error() {
alert("You have refused to display your location. You will not be able to submit stories.");
}
mainGeo();
Perhaps this post in the v3 group: Overlapping markers on your Google Map? Meet OverlappingMarkerSpiderfier might help:
Sounds like the OverlapingMarkerSpiderifier solves your problem.
I have created the maps api below and have an array of addresses that come from a database.
The map loads correctly, however I have the following issue.
The dynamic Markers are not incrementing with the value of "i".. so the map displays all markers with "1" and not "1,2,3,4,5"
// Define Vars
var pinColor = "FE7569";
var marker, i;
// Set default map center location
var latlng = new google.maps.LatLng(-27.79014,153.18049);
// Create pinShadow for each marker
var pinShadow = new google.maps.MarkerImage("http://chart.apis.google.com /chart?chst=d_map_pin_shadow",
new google.maps.Size(40, 37),
new google.maps.Point(0, 0),
new google.maps.Point(12, 35));
// Function to create the dynamic marker
function pinImage(i){
return image = new google.maps.MarkerImage("http://www.googlemapsmarkers.com/v1/"+i+"/"+pinColor+"/", new google.maps.Size(21, 34), new google.maps.Point(0,0), new google.maps.Point(10, 34));
}
// Function to run once page has loaded
function initialize(){
// Set Default settigns for google map
var settings = {
zoom: 10,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
mapTypeId: google.maps.MapTypeId.ROADMAP};
// Start Google Maps and assign it to div on site
var map = new google.maps.Map(document.getElementById("map_canvas"), settings);
// loop though total numner of address in array
for (i = 1; i < total; i++) {
// Use geocoder to grab latlong for user inputed address
geocoder.geocode( { 'address': address[i]}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Redefine map center location
if (i = 1){ map.setCenter(results[0].geometry.location); }
// Create dynamic markers on map as per the address array
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title:address[i],
zIndex: i,
// PROBLEM CODE --- Using the function below it creates all Markers with a "1" instead of the "i" value..??
icon: pinImage(i),
shadow: pinShadow
});
}
});
}
}
The old "function scope wrapper" trick (function(i) {...})(i) works here. Without it, the execution takes the final value of i. Also, if(i = 1) should be if(i == 1)
To play around: http://jsfiddle.net/BK8vv/
for (var i = 1; i < total; i++) {
(function(i) {
// Use geocoder to grab latlong for user inputed address
geocoder.geocode( { 'address': address[i]}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Redefine map center location
if (i == 1){ map.setCenter(results[0].geometry.location); }
// Create dynamic markers on map as per the address array
alert(i);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
title:address[i],
zIndex: i,
// PROBLEM CODE --- Using the function below it creates all Markers with a "1" instead of the "i" value..??
icon: pinImage(i),
shadow: pinShadow
});
}
});
})(i);
}
}
Goal: Get the TEXT address and then display the street view and map view at the same time
Ref Site:
http://code.google.com/apis/maps/documentation/javascript/examples/streetview-simple.html
My site:
http://www.iamvishal.com/dev/property/P2154 (pls click the map view to see the map)
Problem: I am able to display the map and the address correctly but instreet view does not change. Any idea why ?
My js variable address hold the text address in this case "323235 Balmoral Terrace Heaton Newcastle Upon Tyne"
function initialize()
{
var fenway = new google.maps.LatLng(42.345573,-71.098326);
var mapOptions = {
center: fenway,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById("map_canvas"), mapOptions);
var panoramaOptions = {
position: fenway,
pov: {
heading: 34,
pitch: 10,
zoom: 1
}
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById("pano"),
panoramaOptions);
map.setStreetView(panorama);
var geocoderTwo = new google.maps.Geocoder();
geocoderTwo.geocode({"address":address},function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker
({
map: map,
position: results[0].geometry.location
});
}
else
{
alert("Geocode was not successful for the following reason: " + status);
}
}
);
}
Here's how I've created a streetview before:
function createStreetMap(strMapCanvasID, yourLatLng)
{
var panorama;
//once the document is loaded, see if google has a streetview image within 50 meters of the given location, and load that panorama
var sv = new google.maps.StreetViewService();
sv.getPanoramaByLocation(yourLatLng, 50, function(data, status) {
if (status == 'OK') {
//google has a streetview image for this location, so attach it to the streetview div
var panoramaOptions = {
pano: data.location.pano,
addressControl: false,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
}
};
var panorama = new google.maps.StreetViewPanorama(document.getElementById(strMapCanvasID), panoramaOptions);
// lets try and hide the pegman control from the normal map, if we're displaying a seperate streetview map
objCreatedMap.setOptions({
streetViewControl: false
});
}
else{
//no google streetview image for this location, so hide the streetview div
$('#' + strMapCanvasID).parent().hide();
}
});
}
Update: and you could call this function directly from within your existing code (I've amended the function to use a LatLng rather than individual latitude and longitude values:
if (status == google.maps.GeocoderStatus.OK)
{
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker
({
map: map,
position: results[0].geometry.location
});
createStreetMap('yourStreetViewDiv', results[0].geometry.location);
}
There are a couple issues with your code. Fix them first:
64 Uncaught ReferenceError: berkeley is not defined
Also, you'll need to set a zoom and mapTypeId options on your Map before anything shows.
I have 50 markers on my map (V3 of the Google maps API) in an array called spots. I want to add a text field so users can put in their postcode and it will add an additional marker giving them their location in relation to the surrounding markers. I think I am pretty close with what i have below but it won;t output the marker on the map. I think there is a conflict because i already have an array of markers and it doesn't like me adding the additional marker through the function. How do i get that function to add an additional element to the array through the codeAddress() function? Or is that even the right way to do it?
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var myOptions = {
zoom: 14,
center: new google.maps.LatLng(51.51251523, -0.133201961),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
setMarkers(map, spots);
}
var spots = [
['River Street - Clerkenwell', 51.52916347, -0.109970527, '3.png', 2896, 'River Street - Clerkenwell'],
['Phillimore Gardens - Kensington', 51.49960695, -0.197574246, '3.png', 2897, 'Phillimore Gardens - Kensington']
];
function setMarkers(map, locations) {
var image1 = new google.maps.MarkerImage('amber-spot.png',
new google.maps.Size(30, 36),
new google.maps.Point(0,0),
new google.maps.Point(0, 32));
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var spot = locations[i];
var myLatLng = new google.maps.LatLng(spot[1], spot[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: spot[3],
title: spot[0],
zIndex: spot[4],
html: spot[5]
});
var infowindow = new google.maps.InfoWindow({
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(this.html);
infowindow.open(map,this);
});
}
}
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker2 = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
</script>
This is the form for geocoding
<div class="view-content">
<input id="address" type="textbox" value="W1T 4JD">
<input type="button" value="Geocode" onclick="codeAddress()">
<div id="map_canvas" style="width:800px; height:600px;"></div>
I ended up using the proximity postcode filter on the Drupal gmap module to do this. Initially i didn;t think it would work because i wasn't using the gmap modules native map on the View where the filter was being used but i hadn't realised the results would still be in the array that was returned :-).
Lee