My kml is as under
<?xml version="1.0" encoding="utf-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Car Parks</name>
<description>Car Parks</description>
<Folder>
<name>Data Objects</name>
<open>1</open>
<description>data objects</description>
<Placemark id="CP11">
<name>CP11</name>
<description>CP11</description>
<styleUrl>#0-normal</styleUrl>
<Point>
<coordinates>4.878205,52.371968,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
My javascript is as under
geoXml = new geoXML3.parser({
createMarker: createMarker
});
createMarker:function(placemark, doc) {
var markerOptions = {
optimized: false
};
// Create the marker on the map
var marker = new google.maps.Marker(markerOptions);
if (!doc) {
doc.markers.push(marker);
}
google.maps.event.addListener(marker, 'click', function()
{
// I want to access the document name here of 'car Parks'
alert(doc.Document);
});
}
How can I get document name in marker click event of the marker? Basically when I click the marker on the map, I want to know the type of marker the user has clicked on.
There is an optional placemark parse function
pmParseFn
Which is passed a reference to the xml DOM for its associated placemark. example using it
It isn't really designed for your purpose, but if your KML format is fixed, you can get the <name> of the <Document> tag by doing this:
var map;
var geoXml = null;
function initialize() {
var latlong = new google.maps.LatLng(59.32, 13.48);
var googlemaps_options = {
zoom: 18,
center: latlong,
mapTypeId: google.maps.MapTypeId.SATELLITE,
streetViewControl: false
}
map = new google.maps.Map(document.getElementById('map_canvas'), googlemaps_options);
geoXml = new geoXML3.parser({
createMarker: createMarker,
pmParseFn: parsePlacemark,
map:map
});
geoXml.parse("http://www.geocodezip.com/geoxml3_test/SO_20140306_name.kml");
}
// Custom placemark parse function
function parsePlacemark (node, placemark) {
var addressNodes = node.parentNode.parentNode.getElementsByTagName('name');
var address = null;
if (addressNodes && addressNodes.length && (addressNodes.length > 0)) {
placemark.docName = geoXML3.nodeValue(addressNodes[0]);
}
}
function createMarker(placemark, doc) {
var markerOptions = {
optimized: false,
position: placemark.latlng,
map: map
};
// Create the marker on the map
var marker = new google.maps.Marker(markerOptions);
if (!doc) {
doc.markers.push(marker);
}
google.maps.event.addListener(marker, 'click', function()
{
// I want to access the document name here of 'car Parks'
alert(placemark.docName);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
working example
working example with 2 different KML files
Related
I have a project created with ionic. In here I have a Google Map with a places search box.
I have included the Google Map library like so:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=SOMEKEY&libraries=places" defer></script>
Now in my TypeScript code I have the following
// init the google map
initMap() {
var centerOfMap;
var draggableMarker = false;
this.mapHasBeenInitialized = true;
this.isStaticLocation = false;
centerOfMap = new google.maps.LatLng(this.locationService.gpsLat, this.locationService.gpsLong);
draggableMarker = true;
var options = {
center: centerOfMap,
zoom: 11,
fullscreenControl: false,
disableDefaultUI: true, // dont allow default zoom/sattelite/street view
gestureHandline: 'cooperative' // disable moving map with one finger
};
this.map = new google.maps.Map(this.googleMap.nativeElement, options);
this.marker = new google.maps.Marker({
position: centerOfMap,
map: this.map,
draggable: draggableMarker
});
if(!this.isStaticLocation) {
var searchBox = new google.maps.places.SearchBox(this.googleInput.nativeElement);
// add the searchbar to the google map
this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.googleInput.nativeElement);
// Bias the SearchBox results towards current map's viewport
this.map.addListener('bounds-changed', () => {
searchBox.setBounds(this.map.getBounds());
});
searchBox.addListener('places_changed', () => {
var places = searchBox.getPlaces();
if(places.length == 0) {
return;
}
var bounds = new google.maps.LatLngBounds();
places.forEach(place => {
if(!place.geometry) {
console.log("returned place contains no geometry");
return;
}
this.setMarkerLocation(place);
if(place.geometry.viewport) {
bounds.union(place.geometry.viewport);
} else {
bounds.extends(place.geometry.location);
}
});
this.map.fitBounds(bounds);
});
}
if(draggableMarker) {
google.maps.event.addListener(this.marker, 'dragend', (event)=>{
this.getMarkerLocation();
});
}
google.maps.event.addListener(this.map, 'click', (event: any)=> {
var clickedLocation = event.latLng;
this.marker.setPosition(clickedLocation);
this.getMarkerLocation();
});
// neccessary for reload. Made async to trick loading process
setTimeout(()=> {
google.maps.event.trigger(this.googleMap.nativeElement, 'resize');
this.map.setCenter(centerOfMap);
}, 100);
}
// function to set the location marker on a different spot
setMarkerLocation(place: any) {
this.marker.setMap(null);
this.marker = new google.maps.Marker({
position: place.geometry.location,
map: this.map,
draggable: true
});
this.getMarkerLocation();
}
getMarkerLocation() {
var currLoc = this.marker.getPosition();
this.locationService.setGoogleMapsLocation(currLoc.lat(), currLoc.lng());
this.locationChanged = true;
}
And this code works like a charm in the browser and on Android. Basically what the code does is whenever someone taps on the map, the marker position changes to their tap location.
When a person searches for a Place, the places dropdown will show over the map. On android, when you tap a place in this dropdown, the marker will go to the selected place (f.e. australia).
On iOS however, the marker will position itself on the location where the person tapped and will totally ignore the tap on the place dropdown.
So when I'm in Europe and I type in 'Australia' and select 'Australia' from my dropdown, on Android I'll go to australia but on iOS I'll stay somewhere in Europe wherever the dropdown was positioned.
I build a map and add markers. When I'm calling AJAX , Some more records are coming from db and updating the location to map without reloading the map. But the problem is it is making new cluster for new records.
Here is code :
var marker, i;
var markers=[]
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
icon: locations[i][4]
});
google.maps.event.addListener(marker, 'mouseover', (function (marker, i) {
return function () {
infowindow.setContent("<img src="+locations[i][5]+" width='100%'><br> <strong>"+locations[i][0]+"</strong>");
infowindow.open(map, marker);
}
})(marker, i));
// assuming you also want to hide the infowindow when user mouses-out
marker.addListener('mouseout', function() {
infowindow.close();
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent("<img src="+locations[i][5]+" width='100%'><br> <strong>"+locations[i][0]+"</strong>");
infowindow.open(map, marker);
}
})(marker, i));
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers,{
imagePath: 'https://cdn.rawgit.com/googlemaps/js-marker-clusterer/gh-pages/images/m'
});
You can Add markers
var markers = []
var marker = new google.maps.Marker({position: center});
markers.push(marker);
markerClusterer.addMarkers(markers);
Note that here I have added only one.
You can remove all markers
markerClusterer.clearMarkers();
markers = [];
Note that for tidiness I have also unset the markers array here.
you can go through
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/reference.html
I jus started learn ruby on rails and currently I am creating my first rails app. And I ran into some problems. In my app, I would like to get user's position (latitude, longitude). So I can put the button "find me" and return user's locations. But I would like to load my page and show my position (latitude, longitude), don't press any buttons. And then use lat and lng in my controllers. How can I do this?
Add the below script in your view page.You may go ahead and modify this as needed as to show/customise messages and buttons.Remember to have a dedicated div with id="map-canvas" to show you map on the page.
I have used geocomplete.js to show map and allow user to enter places from search box .You may remove the scripts using geocomplete if not needed.
<script type="text/javascript">
// Enable the visual refresh
// google.maps.visualRefresh = true;
var map;
var mapOptions = {
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: '<p>You are here!</p>'
});
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}//initialize ends
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = '<p>Unable to find the current location</p>';
} else {
var content = '<p Your browser doesn\'t support geolocation.</p>';
}
var options = {
map: map,
zoom: 5,
position: new google.maps.LatLng(60, 105),
content: content
};
var marker = new google.maps.Marker({
position: new google.maps.LatLng(60, 105),
map: map,
animation: google.maps.Animation.DROP,
title: 'Sorry,we were unable to find your location'
});
marker.setAnimation(google.maps.Animation.BOUNCE);
var infowindow = new google.maps.InfoWindow(options);
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
infowindow.open(map,marker);
map.setCenter(options.position);
}//handleNoGeolocation ends
//load the page and execute above scripts
$(document).ready(function(){
$('#map-canvas').html("<p class='text-center text-alert'>Loading map...</p>").show(3000);
//load the map after 2 seconds
setTimeout('initialize()', 3000);
// $("#geocomplete").geocomplete({
// map: ".map-canvas-guest"
// });
//you may use this or remove this section using geocomplete.js if not needed.
$("#geocomplete").geocomplete();
$("#geocomplete").geocomplete(mapOptions).bind("geocode:result", function(event, result){
console.log(result.formatted_address);
//use this user entered address and you may call ajax here as well
})
})//document ends
</script>
I have a google map with a load of markers on it, each corresponding to a different post in the html. Each marker id is the same as each post id. Inside the map initialize = function() {... I have the following code (I'm using gon to pass info from rails to javascript):
for (m = 0; m < gon.markers.length; m++) {
marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(gon.markers[m].lat, gon.markers[m].lng),
icon: image,
infowindow: gon.markers[m].infowindow,
id: gon.markers[m].id
});
google.maps.event.addListener(marker, 'mouseover', function() {
var image = $("#map-canvas").data('marker2');
this.setIcon(image);
// console.log("marker.id: " + marker.id);
// console.log("this.id" + this.id);
$('#' + marker.id).css('background', 'red');
});
google.maps.event.addListener(marker, 'mouseout', function() {
var image = $("#map-canvas").data('marker1');
this.setIcon(image);
$('#' + marker.id).css('background', 'white');
});
markers[markers.length] = marker;
}
Uncommenting the console.log lines demonstrates that it is the classic closure problem (marker.id always has the same value no matter which marker is hovered on).
My question is, how do I code it properly so it does as intended? I just can't get the code right now matter what I try. I've tried stuff like this but is just doesn't work:
marker.on('mouseover', noticeHover(marker.id));
function noticeHover(id) {
var image = $("#map-canvas").data('marker2');
this.setIcon(image);
$('#' + id).css('background', 'gainsboro');
}
Wrap the entire code that handles the marker-creation into a function and pass the items inside the loop as argument to this function:
for (m = 0; m < gon.markers.length; m++) {
//anonymous,self-executing function
(function(props){
var goo = google.maps,
marker = new goo.Marker({
map: map,
position: new goo.LatLng(props.lat,
props.lng),
icon: image,
infowindow: props.infowindow,
id: props.id
});
goo.event.addListener(marker, 'mouseover', function() {
var image = $("#map-canvas").data('marker2');
this.setIcon(image);
$('#' + marker.id).css('background', 'red');
});
goo.event.addListener(marker, 'mouseout', function() {
var image = $("#map-canvas").data('marker1');
this.setIcon(image);
$('#' + marker.id).css('background', 'white');
});
markers.push(marker);
}(
gon.markers[m]//pass current loop-item as argument
));
}
I'm writing an extension that involving adding an item to Firefox's context menu, but it appends to the end of the menu and I couldn't find any pointers customizing item's position using Addon SDK (insertBefore/insertAfter), I know how this can be done using XUL, but I'm trying to do it using Addon SDK or some sort of Addon SDK/XUL combination
This is the code snippet related to context menu
main.js
var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;
var tabs = require("sdk/tabs");
var cm = require("sdk/context-menu");
pageMod.PageMod({
include: "*.youtube.com",
contentScriptFile: data.url("page.js"),
onAttach: function (worker) {
worker.port.emit('link', data.url('convertbutton.png'));
}});
cm.Item({
label: "Convert File",
image: data.url("bighdconverterlogo128png.png"),
context: [
cm.URLContext(["*.youtube.com"]),
cm.PageContext()
],
contentScriptFile: data.url("menu.js"),
onMessage: function(vUrl){
tabs.open(vUrl);
}
});
data/menu.js
self.on("click", function(){
self.postMessage('http://hdconverter.co/' + 'c.php?url=' + window.location.href);
});
Thanks
i dont know about sdk but for non-sdk addons its easy. but because you dont have the boiler plate setup its going to look long. add this code to your addon at the bottom:
var positionToInsertMenu = 0; //set the position you want it at here
var myLabelText = 'Convert File';
const {interfaces: Ci,utils: Cu} = Components;
Cu.import('resource://gre/modules/Services.jsm');
/*start - windowlistener*/
var windowListener = {
//DO NOT EDIT HERE
onOpenWindow: function (aXULWindow) {
// Wait for the window to finish loading
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
aDOMWindow.addEventListener("load", function () {
aDOMWindow.removeEventListener("load", arguments.callee, false);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}, false);
},
onCloseWindow: function (aXULWindow) {},
onWindowTitleChange: function (aXULWindow, aNewTitle) {},
register: function () {
// Load into any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}
// Listen to new windows
Services.wm.addListener(windowListener);
},
unregister: function () {
// Unload from any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.unloadFromWindow(aDOMWindow, aXULWindow);
}
//Stop listening so future added windows dont get this attached
Services.wm.removeListener(windowListener);
},
//END - DO NOT EDIT HERE
loadIntoWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
var contentAreaContextMenu = aDOMWindow.document.getElementById('contentAreaContextMenu');
var myMenuItem;
if (contentAreaContextMenu) {
var menuItems = contentAreaContextMenu.querySelector('menuitem');
[].forEach.call(menuItems, function(item) {
if (item.getAttribute('label') == myLabelText) {
myMenuItem = item;
}
});
contentAreaContextMenu.removeChild(myMenuItem);
if (contentAreaContextMenu.childNodes.length >= positionToInsertMenu) { //position is greater then number of childNodes so append to end
contentAreaContextMenu.appendChild(myMenuItem);
} else {
contentAreaContextMenu.insertBefore(myMenuItem, contentAreaContextMenu.childNodes[thePosition]);
}
}
},
unloadFromWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
var myMenuItem = aDOMWindow.document.getElementById('myMenuItem');
if (myMenuItem) {
myMenuItem.parentNode.removeChild(myMenuItem);
}
}
};
windowListener.register();
on unload of your addon add this:
windowListener.unregister();
i copied pasted from a template and modded it real fast. for position to be accurate you probably have to consider which menuitems are hidden and which are not