How to use KML file in Google Maps for OFBiz? - google-maps

I'm trying to use KML file in Google Maps in OFBiz framework for a web application.I'm inputing the co-ordinates value in a array(list). So, how can i begin using Kml file in Google Maps??
I have inserted code of google maps in .ftl file
function initialize() {
var map;
var bounds = new google.maps.LatLngBounds();
var mapOptions = {
mapTypeId: 'satellite'
};
// Display a map on the page
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);
// Multiple Markers
var markers = [
['London Eye, London', 51.503454,-0.119562],
['Palace of Westminster, London', 51.499633,-0.124755]
];
// Info Window Content
var infoWindowContent = [
['<div class="info_content">' +
'<h3>London Eye</h3>' +
'<p>The London Eye is a giant Ferris wheel situated on the banks of the River Thames. The entire structure is 135 metres (443 ft) tall and the wheel has a diameter of 120 metres (394 ft).</p>' + '</div>'],
['<div class="info_content">' +
'<h3>Palace of Westminster</h3>' +
'<p>The Palace of Westminster is the meeting place of the House of Commons and the House of Lords, the two houses of the Parliament of the United Kingdom. Commonly known as the Houses of Parliament after its tenants.</p>' +
'</div>']
];
// Display multiple markers on a map
var infoWindow = new google.maps.InfoWindow(), marker, i;
var infoWindow1 = [];
for( i = 0; i < farmerCropList.length; i++ ) {
var position = new google.maps.LatLng(farmerCropList[i].latitude, farmerCropList[i].longitude);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: farmerCropList[i].farmerCropId
});
infoWindow1[i] = new google.maps.InfoWindow({
content: '<div style="padding:5px;width:100%;height:auto;">' +
'<div style="padding:5px;width:400px;font-size:16px;text-align:left">Farmer Name : '+(farmerCropList[i].firstName + farmerCropList[i].lastName)+'</div>'+
'</div>'
});
var lastOpen = -1;
google.maps.event.addListener(marker, 'click', (function(marker, i) {
if (lastOpen > -1) {
infoWindow1[lastOpen].close();
}
return function(){
infoWindow1[i].open(map, marker);
}
lastOpen = i;
})(marker, i));
map.fitBounds(bounds);
}
var boundsListener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
this.setZoom(15);
google.maps.event.removeListener(boundsListener);
});
google.maps.event.addDomListener(window, 'load', initialize);
}

You can use a KmlLayer
see this google developer sample
https://developers.google.com/maps/documentation/javascript/examples/layer-kml

Related

How to find the exact location details from latitude and longitude?

I tried using Google Maps API for 'Reverse Geocoding' to get the location by providing latitude and longitude. This gives the street address, city and country info. But I need to get the exact details like building name, shop name etc. For example, while querying the co-ordinates "72.9011206,19.0517508", Google Maps API gives "Plot No 5, VN Purav Marg, Borla, Union Park, Chembur, Mumbai, Maharashtra 400071, India". But I need to get the name of the shop "Barista Lavazza" as available in 'Google Earth' for the same co-ordinate details.
One option would be to use the Google Maps Javscript API Places library nearbySearch, search the returned results for the closest result to the requested position.
proof of concept fiddle
code snippet:
var map;
var infowindow;
var searchLoc = new google.maps.LatLng(19.0517508, 72.9011206);
function initialize() {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: searchLoc,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
infowindow = new google.maps.InfoWindow();
var request = {
location: searchLoc,
radius: '50'
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var bounds = new google.maps.LatLngBounds();
var distMin = Number.MAX_VALUE;
var idxMin = -1;
for (var i = 0; i < results.length; i++) {
var place = results[i];
bounds.extend(results[i].geometry.location);
var distance = google.maps.geometry.spherical.computeDistanceBetween(results[i].geometry.location, searchLoc);
if (distance < distMin) {
distMin = distance;
idxMin = i;
}
}
var marker = createMarker(results[idxMin]);
google.maps.event.trigger(marker, 'click');
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent("<h2 style='color:blue'>"+place.name + "</h2><br>" + place.vicinity + "<br>" + marker.getPosition().toUrlValue(7));
infowindow.open(map, this);
});
return marker;
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places"></script>
<div id="map_canvas"></div>

Google maps showing same info window for all markers

I'm looping over an array of properties and create multiple markers on a google map. I'd like each of these markers to have their own info window content. My code looks right to me but it's not working. Can somebody point me in the right direction.
Here is my current code
for (var i = startRow; i < AMdata.property.length; i++) {
var propertyDetails = AMdata.property[i];
var latLng = new google.maps.LatLng(propertyDetails.LATITUDE, propertyDetails.LONGITUDE);
bounds.extend(latLng);
var marker = new google.maps.Marker({
position: latLng,
title: propertyDetails.NAME,
icon: outIcon
});
// add an event listener for this marker
google.maps.event.addListener(marker , 'click', function() {
// assuming you have some content in a field called Field123
infowindow.setContent('<div class="infowindow"><div class="panel-image listing-img"><img style="max-height:115px;" width="100%" src="' + propertyDetails.THUMBNAIL + '"></div><p>' + propertyDetails.NAME + '</p></div>');
infowindow.open(map, this);
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
map.fitBounds(bounds);
try this way :
for (var i = startRow; i < AMdata.property.length; i++) {
var propertyDetails = AMdata.property[i];
var latLng = new google.maps.LatLng(propertyDetails.LATITUDE, propertyDetails.LONGITUDE);
bounds.extend(latLng);
var marker = new google.maps.Marker({
position: latLng,
title: propertyDetails.NAME,
icon: outIcon
});
// add an event listener for this marker
k = markers.push(marker);
google.maps.event.addListener(markers[k-1] , 'click', function(propertyDetail) {
// assuming you have some content in a field called Field123
infowindow.setContent('<div class="infowindow"><div class="panel-image listing-img"><img style="max-height:115px;" width="100%" src="' + propertyDetails.THUMBNAIL + '"></div><p>' + propertyDetails.NAME + '</p></div>');
infowindow.open(map, this);
});
}
var markerCluster = new MarkerClusterer(map, markers);
map.fitBounds(bounds);

Show all infowindows open

I'm trying to have custom infowindows float above markers, however I noticed that only one marker can be opened at any one time. Is there a workaround to this?
Here's the code I have produced at the moment:
downloadUrl("AllActivityxml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("id");
var address = markers[i].getAttribute("id");
var type = markers[i].getAttribute("venue_type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng"))
);
var infowindow = new google.maps.InfoWindow();
var html = "<b>" + point + "</b>hello <br/>" + type;
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
markersArray.push(marker);
bindInfoWindow(marker, map, infoWindow, html);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map,marker);
});
}
});
And when you check this map, notice that I cannot open more than 2 infowindows at once. Why is that?
There is no limitation implicit to the Google Maps API v3 that makes only one InfowWindow available at a time. You need to write your code to do that. If you want an InfoWindow for each marker, make one.
Some thing like (not tested):
function createMarker(latlng, html) {
var contentString = html;
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
position: latlng,
map: map,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
}

Google maps infowindow

I am trying to create listeners for some map markers. I can create the markers and they are on the map but, no matter which marker I click on it tells me "Uncaught TypeError: Cannot call method 'open' of undefined" . When I break at the open code it is showing markers[46] which is one more that the highest index. And it doesnt matter which marker I click on its always the same index.
EDIT: I edited the code and pasted all of it. No errors, but nothing happens when I click a marker. I am looking in Chrome and it looks like there isnt a event handler registered
<script>
var map;
var nav = [];
$(document).ready(function () {
//initialise a map
init();
var infowindow = new google.maps.InfoWindow({});
$.get("xxxxxx.kml", function (data) {
html = "";
//loop through placemarks tags
i = 1;
$(data).find("Placemark").each(function (index, value) {
//get coordinates and place name
coords = $(this).find("coordinates").text();
contentString = $(this).find("description").text();
var partsOfStr = coords.split(',');
var lat = parseFloat(partsOfStr[0]);
var lng = parseFloat(partsOfStr[1]);
var myLatLng = new google.maps.LatLng(lng, lat);
place = $(this).find("name").text();
createMarker(myLatLng, place, contentString, i)
//store as JSON
c = coords.split(",")
nav.push({
"place": place,
"lat": c[0],
"lng": c[1]
})
//output as a navigation
html += "<li>" + place + "</li>";
i++;
});
//output as a navigation
$(".navigation").append(html);
//bind clicks on your navigation to scroll to a placemark
$(".navigation li").bind("click", function () {
panToPoint = new google.maps.LatLng(nav[$(this).index()].lng, nav[$(this).index()].lat)
map.panTo(panToPoint);
})
});
markers = [];
function createMarker(myLatLng, title, contentString, i) {
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: title
});
google.maps.event.addListener(markers, 'click', function () {
infoWindow.setContent(contentString);
infowindow.open(map, markers[i]);
});
markers[i] = marker;
return marker
}
function init() {
//google.maps.event.addDomListener(window, 'init', Initialize);
var latlng = new google.maps.LatLng(39.047050, -77.131409);
var myOptions = {
zoom: 4,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
}
})
This is almost a FAQ. When your loop ends, the value of i is 46 (based on your statement). There is no marker 46, so all the click listeners fail. It can be solved with function closure (a createMarker function which holds the association between the marker and the infowindow contents).
Something like this in your example (not tested), call it from inside your marker creation loop, requires a global markers array, but doesn't require the global infowindow array:
//global markers array
markers = [];
// global infowindow
var infowindow = new google.maps.InfoWindow({});
// createMarker function
function createMarker(myLatLng, title, contentString, i)
{
var marker = new google.maps.Marker({
position: myLatlng ,
map: map,
title:title
});
google.maps.event.addListener(markers, 'click', function() {
infoWindow.setContent(contentString);
infowindow.open(map,markers[i]);
});
markers[i] = marker;
return marker
}

InfoWindow on Marker using MarkerClusterer

This is my html code. I've try anything to add an infowindow on the markers but it don't wanna work. My data is loading from the "Alle_Ortswahlen.page1.xml" file.
Do anyone have an idea how can I add infoWindow to each marker?
<script type="text/javascript">
google.load('maps', '3', {
other_params: 'sensor=false'
});
google.setOnLoadCallback(initialize);
function initialize() {
var stack = [];
var center = new google.maps.LatLng(48.136, 11.586);
var options = {
'zoom': 5,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
GDownloadUrl("Alle_Ortswahlen.page1.xml", function(doc) {
var xmlDoc = GXml.parse(doc);
var markers = xmlDoc.documentElement.getElementsByTagName("ROW");
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("Field4"));
var lng = parseFloat(markers[i].getAttribute("Field6"));
var marker = new google.maps.Marker({
position : new google.maps.LatLng(lat, lng),
map: map,
title:"This is a marker"
});
stack.push(marker);
}
var mc = new MarkerClusterer(map,stack);
});
}
</script>
Before the for cycle, make an empty infowindow object.
var infowindow = new google.maps.InfoWindow();
Than in the for cycle, after the marker, add an event listener, like this:
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent("You might put some content here from your XML");
infowindow.open(map, marker);
}
})(marker, i));
There is some closure magic happening when passing the callback argument to the addListener method. If you are not familiar with it, take a look at here:
Mozilla Dev Center: Working with Closures
So, your code should look something like this:
google.load('maps', '3', {
other_params: 'sensor=false'
});
google.setOnLoadCallback(initialize);
function initialize() {
var stack = [];
var center = new google.maps.LatLng(48.136, 11.586);
var options = {
'zoom': 5,
'center': center,
'mapTypeId': google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), options);
var infowindow = new google.maps.InfoWindow();
GDownloadUrl("Alle_Ortswahlen.page1.xml", function(doc) {
var xmlDoc = GXml.parse(doc);
var markers = xmlDoc.documentElement.getElementsByTagName("ROW");
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("Field4"));
var lng = parseFloat(markers[i].getAttribute("Field6"));
var marker = new google.maps.Marker({
position : new google.maps.LatLng(lat, lng),
map: map,
title:"This is a marker"
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent("You might put some content here from your XML");
infowindow.open(map, marker);
}
})(marker, i));
stack.push(marker);
}
var mc = new MarkerClusterer(map,stack);
});
}
So what you need to do is add some code, inside your for-loop, associating an infowindow onclick event handler with each marker. I'm assuming you only want to have 1 infowindow showing at a time, i.e. you click on a marker, the infowindow appears with relevant content. If you then click on another marker, the first infowindow disappears, and a new one reappears attached to the other marker. Rather than having multiple infowindows all visible at the same time.
GDownloadUrl("Alle_Ortswahlen.page1.xml", function(doc) {
var xmlDoc = GXml.parse(doc);
var markers = xmlDoc.documentElement.getElementsByTagName("ROW");
// just create one infowindow without any content in it
var infowindow = new google.maps.InfoWindow({
content: ''
});
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].getAttribute("Field4"));
var lng = parseFloat(markers[i].getAttribute("Field6"));
var marker = new google.maps.Marker({
position : new google.maps.LatLng(lat, lng),
map: map,
title:"This is a marker"
});
// add an event listener for this marker
google.maps.event.addListener(marker , 'click', function() {
// assuming you have some content in a field called Field123
infowindow.setContent(markers[i].getAttribute("Field123"));
infowindow.open(map, this);
});
stack.push(marker);
}
var mc = new MarkerClusterer(map,stack);
});