I'm new with Openlayers, so not sure what is wrong. I can add markers when I change a select drop down and when I click the map. The issue comes when I zoom the map, the markers disappear.
I realised that markers don't disappear, they just move to another place, to the point 0,0.
This is the code
(function($) {
$().ready(function() {
var ZOOM_LEVEL_PROVINCE = 12;
var projection = new OpenLayers.Projection("EPSG:4326");
var map;
var markerLayer;
var initMap = function() {
map = new OpenLayers.Map ("map", {
controls:[
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.Permalink(),
new OpenLayers.Control.ScaleLine({geodesic: true}),
new OpenLayers.Control.Permalink('permalink'),
new OpenLayers.Control.MousePosition(),
new OpenLayers.Control.Attribution()],
//maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
maxResolution: 156543.0339,
numZoomLevels: 19,
units: 'm',
projection: new OpenLayers.Projection("EPSG:4326"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
} );
layer = new OpenLayers.Layer.OSM("Simple OSM Map");
map.addLayer(layer);
var point = getLonLatProvince('san-jose');
map.setCenter(point.transform(projection, map.getProjectionObject()), ZOOM_LEVEL_PROVINCE);
}
var initMakerLayer = function(){
markerLayer = new OpenLayers.Layer.Markers( "MarkerLayer" );
markerLayer.id = "MarkerLayer";
map.addLayer(markerLayer);
}
var showMarker = function( province ){
var point = getLonLatProvince(province);
var location = point.transform(projection, map.getProjectionObject());
showMarkerPosition(location);
}
var showMarkerPosition = function( location ){
markerLayer.clearMarkers();
var size = new OpenLayers.Size(21,25);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png',size,offset);
markerLayer.addMarker(new OpenLayers.Marker(location,icon.clone()));
var newPoint = location.transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
$("#edit-plonlat").val( newPoint );
}
var getLonLatProvince = function( province ){
...
}
initMap();
initMakerLayer();
showMarker('san-jose');
map.events.register("click", map, function(e) {
var location = map.getLonLatFromPixel(e.xy);
showMarkerPosition(location);
});
$('#edit-pprovinces').change(function() {
var selectedPronvince = $(this).val();
var point = getLonLatProvince(selectedPronvince);
showMarker(selectedPronvince);
map.setCenter(point.transform(projection, map.getProjectionObject()), ZOOM_LEVEL_PROVINCE);
});
});
})(jQuery);
I think your call to map.getLonLatFromPixel(e.xh) is getting a location in WGS84 (EPSG:4326) since that is the projection of the map. Then you call showMarkerPosition in your "click" handler. In showMarkerPosition you transform that location from the Google to WGS84 projection, which would change a large lat/lon in meters to a much smaller lat/lon in degrees.
If you've started out with degrees for that meters-to-degrees transform, then I think you'll end up with a lat/lon that's very close to 0,0 off the West coast of Africa.
A projection transform issue is where I always start looking when I see 0,0 lat/lon's.
Related
Some time ago, the map.layers.clear() method would not remove the polyline from the map, but now, after some Bing update, the polyline is being removed when map.layers.clear() is called. How can I solve this?
Map initialize
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'Your Bing Maps Key',
center: new Microsoft.Maps.Location(47.606209, -122.332071),
zoom: 12
});
Here add pushpins
// Add pushpins
function addPushpins() {
// Generate an array of 10 random pushpins within current map bounds
var pushpins = Microsoft.Maps.TestDataGenerator.getPushpins(10, map.getBounds());
var layer = new Microsoft.Maps.Layer();
layer.add(pushpins);
map.layers.insert(layer);
}
Here is update direction callback
// On update directions callback
function onUpdateDirections() {
map.layers.clear();
}
Call addPushpins function
addPushpins();
Here is the Bing Maps Direction Manager sample code
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function() {
var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
// Set Route Mode to driving
directionsManager.setRequestOptions({
routeMode: Microsoft.Maps.Directions.RouteMode.driving
});
// Callback for on update directions
Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', onUpdateDirections);
var waypoint1 = new Microsoft.Maps.Directions.Waypoint({
address: 'Redmond',
location: new Microsoft.Maps.Location(47.67683029174805, -122.1099624633789)
});
var waypoint2 = new Microsoft.Maps.Directions.Waypoint({
address: 'Seattle',
location: new Microsoft.Maps.Location(47.59977722167969, -122.33458709716797)
});
directionsManager.addWaypoint(waypoint1);
directionsManager.addWaypoint(waypoint2);
// Set the element in which the itinerary will be rendered
directionsManager.setRenderOptions({
itineraryContainer: document.getElementById('printoutPanel')
});
directionsManager.calculateDirections();
});
UPDATE - Removes partials pushpins
// Map initialize
var map, pushpins, layer;
map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'Your Bing Maps Key',
center: new Microsoft.Maps.Location(47.606209, -122.332071),
zoom: 12
});
// Here is the Bing Maps Direction Manager sample code
Microsoft.Maps.loadModule('Microsoft.Maps.Directions', function() {
var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
// Set Route Mode to driving
directionsManager.setRequestOptions({
routeMode: Microsoft.Maps.Directions.RouteMode.driving
});
var waypoint1 = new Microsoft.Maps.Directions.Waypoint({
address: 'Redmond',
location: new Microsoft.Maps.Location(47.67683029174805, -122.1099624633789)
});
var waypoint2 = new Microsoft.Maps.Directions.Waypoint({
address: 'Seattle',
location: new Microsoft.Maps.Location(47.59977722167969, -122.33458709716797)
});
directionsManager.addWaypoint(waypoint1);
directionsManager.addWaypoint(waypoint2);
// Callback for on update directions
Microsoft.Maps.Events.addHandler(directionsManager, 'directionsUpdated', onUpdateDirections);
directionsManager.calculateDirections();
});
// On update directions callback
function onUpdateDirections() {
clearLayers();
window.setTimeout(function() {
addPushpins();
}, 2000);
}
// Add pushpins
function addPushpins() {
// Generate an array of 10 random pushpins within current map bounds
pushpins = Microsoft.Maps.TestDataGenerator.getPushpins(10, map.getBounds());
layer = new Microsoft.Maps.Layer();
layer.add(pushpins);
map.layers.insert(layer);
}
// Clear layers
function clearLayers() {
// map.layers.clear();
if (layer !== undefined) {
var currentPrimitives = layer.getPrimitives();
/* remove those that are Pushpins */
for (var i = 0; i < currentPrimitives.length; i++) {
var entity = currentPrimitives[i];
if (entity instanceof Microsoft.Maps.Pushpin){
layer.remove(entity);
}
}
}
}
This is to be expected. It not clearing in the past would have been considered a bug. If you want to clear your layers, but leave the directions you have two options. Clear the layers before calculating the directions, or clear the individual layer rather than all layers in the map.
You could examine your layer, get the primitives from it and remove only the pins. Something like the following:
var currentPrimitives = layer.getPrimitives();
/* remove those that are Pushpins */
for (var i = 0; i < currentPrimitives.length; i++) {
var entity = currentPrimitives[i];
if (entity instanceof Microsoft.Maps.Pushpin){
layer.remove(entity);
}
}
I was looking for a way to retrive all the addresses inside a polygon in a map (google map?). I saw in this post that someone said that is not possible..
I ask this: if is possible to retrive the address from a point on the map, why is not possible to do the same in a polygon? Can't you just: - set an hypoteticl grid in the area of the polygon - for every intersection point of the grid retrive the location address - store the address (if is already stored delete it).
Wouln't this method be workable? thanks Francesco
Looking around I'm almost find a way to do that, merging up various methods.. I'm new in js, so my code is probably full of dumb stuff..
Anyway, I reached a point where I managed to retrive my unique addresses into an array, but can't complete the job beacuse I always get the error of OVER_QUERY_LIMIT, beacuse I send too many requests as explainedin this page
So I think there is no way to do this, unless you want to spend a lot in buying the billing to unlock higher quotas, and this will be a very hard hit beacuse a method like this will require thousands of request each call.
Anyway, this is the code, inserted into the one found here , wich I got from Polygon Drawing and Getting Coordinates with Google Map API v3
Sorry again for the various newbie stuff you will find in it.
var arrAddress=[]; //global
var arrCoord=[]; //global
function selPoly(shape) { //after create polygon do the job
var latlngStr=[];
var lat,lng;
var polCoords = [];
posstr = "" + selectedShape.position;
if (typeof selectedShape.position == 'object') {
posstr = selectedShape.position.toUrlValue();
}
if (typeof selectedShape.getPath == 'function') {
var mycoord="";
var partlng, partlng;
for (var i = 0; i < selectedShape.getPath().getLength(); i++) {
// .toUrlValue(5) limits number of decimals, default is 6 but can do more
mycoord=selectedShape.getPath().getAt(i).toUrlValue();
latlngStr = mycoord.split(',');
//create array with polygon path
polCoords.push(new google.maps.LatLng(latlngStr[0] , latlngStr[1]));
//add 0s to lat
lat=latlngStr[0];
partlat = latlngStr[0].substring(latlngStr[0].indexOf(".") + 1);
switch(partlat.length) {
case 4:
lat =lat +"00";
break;
case 5:
lat =lat +"0";
break;
}
//add 0s to lng
lng=latlngStr[1];
partlng = latlngStr[1].substring(latlngStr[1].indexOf(".") + 1);
switch(partlng.length) {
case 4:
lng =lng +"00";
break;
case 5:
lng =lng +"0";
break;
}
arrCoord.push(lat+","+lng);
}
};
//find higher and lower lat and lng in the polygon, converting lan e lng to number
var maxlat=0, maxlng=0;minlat=99999999,minlng=9999999;
var latlngStr=[];
for(var i=0;i<arrCoord.length;i++) {
latlngStr = arrCoord[i].split(',');
console.log(latlngStr);
lat = parseInt(latlngStr[0].replace(".", ""));
console.log(lat);
lng = parseInt(latlngStr[1].replace(".", ""));
if (lat>maxlat){
maxlat=lat;
};
if (lng>maxlng){
maxlng=lng;
};
if (lat<minlat){
minlat=lat;
};
if (lng<maxlng){
minlng=lng;
};
};
//create new polygon with that path
var polygon = new google.maps.Polygon({
paths: polCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
//move from (minlan,minlng) every 100 horizontal until reach maxlan, then add 200 to lng and star again.
var coordinate;
var newlat="",newlng="";
for (var i=minlat;i<maxlat;i+=100){
for (var j=minlng;j<maxlng;j+=200){
//reconvert lat e lng from number to string
newlat=i.toString();
newlng=j.toString();
newlat=newlat.substring(0,newlat.length-6) + "." +newlat.substring(newlat.length-6,6);
newlng=newlng.substring(0,newlng.length-6) + "." +newlng.substring(newlng.length-6,6);
coordinate=newlat +"," + newlng;
//for every point find out if is inside the polygon
var isWithinPolygon = polygon.containsLatLng(parseFloat(newlat),parseFloat(newlng));
if(isWithinPolygon){
newgeocodeLatLng(function(addr){
if (arrAddress.length==0){arrAddress.push(addr);} else{
for (var i =0; i<arrAddress.length;i++){
var ok=0;
///if address (retrive only the street name) found from point is already in the array, don't put in it. i'm sure there is a better ay to do it....
if (arrAddress[i].split(',')[0]==addr.split(',')[0]){
ok=1;};
};
if(ok==0){arrAddress.push(addr);
};
};
},coordinate); //end newgeocodelatlng
}; //end if iswithpolygon
};//end for j
};//end for i
};
function newgeocodeLatLng(callback,mycoord) {
var address;
var latlngStr = mycoord.split(',');
getReverseGeocodingData(function(addr){
address=addr;
callback(address);
// console.log("address4=" + address);
},latlngStr[0], latlngStr[1]);
};
function getReverseGeocodingData(callback,lat, lng) {
var address="";
var latlng = new google.maps.LatLng(lat, lng);
// This is making the Geocode request
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status !== google.maps.GeocoderStatus.OK) {
alert(status);
}
// This is checking to see if the Geoeode Status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
callback(results[0].formatted_address);
}
});
}
I'm trying to import markers from .js file into my Google Maps.
I use Google Maps Javascript API v3.
If the .js file has too many markers, the map doesn't show any marker.
When I delete some markers in .js file, the map shows all markers from .js file.
What's wrong with this?
I want to import 1,000 ~ 3,000 markers from .js file and show the markers only in the visible bound on the map.
Is there any limitation of the markers while reading .js file?
I don't use JQuery, node.js.
Do I have to callback function? Please help me.
Thanks in advance.
a.html
...
<script src="js/markers.js"></script>
...
<script type="text/javascript">
var mymap; // one map
...
function showMarker(eachLocations) {
// get the center of the map and zoom level
var new_center = mymap.getCenter();
defaultLat = new_center.lat();
defaultLon = new_center.lng();
var zoomLevel = mymap.getZoom();
var marker,i;
var pin_image_url = "/common/images/marker_img.png";
var myMarkerIcon;
var bounds = mymap.getBounds();
var ne = bounds.getNorthEast(); // LatLng of the north-east corner
var sw = bounds.getSouthWest(); // LatLng of the south-west corder
var nw = new google.maps.LatLng(ne.lat(), sw.lng());
var se = new google.maps.LatLng(sw.lat(), ne.lng());
// for each location
for (i = 0; i < eachLocations.length; i++) {
// custom marker
myMarkerIcon = new
google.maps.MarkerImage(pin_image_url,null,null,null,new
google.maps.Size(32,37));
if (eachLocations[i][1] >= se.lat() && eachLocations[i][1] <= nw.lat() && eachLocations[i][2] >= nw.lng() && eachLocations[i][2] <= se.lng()) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(eachLocations[i][1], eachLocations[i][2]),
map: mymap,
icon: myMarkerIcon
});
markers.push(marker);
// listner for marker
google.maps.event.addListener(marker, 'click', (function(marker, i) {
// click,dblclick,mouseup,mousedown,mouseout
return function() {
// if any infowindow has already shown, hides it and shows the new one
if (infowindow) infowindow.close();
// make the infoWindow of the first marker
infowindow = new google.maps.InfoWindow({
map: mymap,
position: new google.maps.LatLng(eachLocations[i][1], eachLocations[i][2])
});
infowindow.setContent('<div style="width:250px;text-align: center;font-size:10pt;font-family:Arial,Verdana;font-weight:bold";>'+eachLocations[i][0]+'</div>');
infowindow.open(mymap, marker);
}
})(marker, i));
} // end of if the location is in the bounds
} // end of for each locations
} // end of function
function initialize() {
var mapDiv=document.getElementById("mapholder");
var myOptions={
center:new google.maps.LatLng(defaultLat,defaultLon),
zoom:defaultZoomLevel,
mapTypeId:google.maps.MapTypeId.ROADMAP,
zoomControl: true, // by default
zoomControlOptions: {style: google.maps.ZoomControlStyle.LARGE},
mapTypeControl:false,
navigationControlOptions:
{style:google.maps.NavigationControlStyle.SMALL}
};
// make map instance
mymap=new google.maps.Map(mapDiv,myOptions);
// Create the DIV to hold the control and
// call the CenterControl() constructor passing in this DIV
var centerControlDiv = document.createElement('div');
var centerControl = new CenterControl(centerControlDiv, mymap);
centerControlDiv.index = 1;
mymap.controls[google.maps.ControlPosition.BOTTOM_LEFT].push( centerControlDiv);
getLocation();
google.maps.event.addListener(mymap, 'idle', function(ev){
var new_center = mymap.getCenter();
defaultLat = new_center.lat();
defaultLon = new_center.lng();
// you may have too many markers problem
// so, before sending array, you have to rearrange markers to show
var bounds = mymap.getBounds();
var ne = bounds.getNorthEast(); // LatLng of the north-east corner
var sw = bounds.getSouthWest(); // LatLng of the south-west corder
var nw = new google.maps.LatLng(ne.lat(), sw.lng());
var se = new google.maps.LatLng(sw.lat(), ne.lng());
var markers2show = [];
var lengthofarray = myLocations.length;
for (i=0;i<myLocations.length;i++) {
// limit the markers for the new bound
if (myLocations[i][1] >= se.lat() && myLocations[i][1] <= nw.lat() && myLocations[i][2] >= nw.lng() && myLocations[i][2] <= se.lng()) {
markers2show.push(myLocations[i]);
}
}
showMarker(markers2show);
});
// close the previous info window of marker when click the map
google.maps.event.addListener(mymap, 'click', function() {
infowindow.close();
});
showMarker(myLocations);
}
...
<body onload="initialize()">
...
js/markers.js
var myLocations = [
['A Location',37.007756,140.750864],
['B Location',37.111598,140.424843],
['C Location',36.881268,140.025215]
];
http://plnkr.co/edit/Zd9GwG?p=preview
I am working on this google map + angular.js example . I want to change the location center dynamically depend on the variable .i.e. I want to make it dynamic center. Please suggest how to do this ?
I want to do some thing Like this.
// Code goes here
//Add the requried module 'angular-ui' as a dependency
angular.module('maptesting', ['ui.directives']);
function MapCtrl($scope) {
$scope.lat = 35.120922 ;
$scope.long = -89.97731 ;
var ll = new google.maps.LatLng($scope.lat, $scope.long);
$scope.mapOptions = {
center: ll,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//Markers should be added after map is loaded
$scope.onMapIdle = function() {
//alert("DF");
if ($scope.myMarkers === undefined){
var marker = new google.maps.Marker({
map: $scope.myMap,
position: ll
});
$scope.myMarkers = [marker, ];
}
};
$scope.showMarkerInfo = function(marker) {
$scope.myInfoWindow.open($scope.myMap, marker);
};
$scope.changeval = function(){
$scope.lat = 13.0810 ;
$scope.long = 80.2740 ;
};
}
You need to watch for changes in the scope in order to refresh the map.
Demo Plunkr
(just use the input fields above the map to change the center of the map in real time)
The important part is $scope.$watch:
var updateCenter = function() {
var ll = new google.maps.LatLng($scope.lat, $scope.long);
$scope.myMap.panTo(ll);
// eventually more stuff
}
$scope.$watch('lat', updateCenter);
$scope.$watch('long', updateCenter);
I am trying to make an application which displays a map with your current location marker and several markers related to data from the server which location is closed to your current location. So far I can render the map, show the current location and get the data related to this location. The problem arise when I try to add markers about the location of this data.
I´ve read through a lot of forums and pages but I found no solution.
I use this piece of code to add markers (to try to add them ..):
var marker = new google.maps.Marker({
map: map._map,
position: new google.maps.LatLng(bookletMarker[i].location[1],bookletMarker[i].location[0]),
title : bookletMarker[i].title,
draggable:false,
icon: "point.png"
});
//This code renders a map with 2 points and displays the route to travel from point A to point B
//On Map Render
onMapMaprender: function(map, gmap, eOpts) {
var record = Ext.getCmp('Panel').getData();
var map = Ext.ComponentQuery.query('#LocationMap')[0].getMap();
var polyline = new google.maps.Polyline();
var markerImage = new google.maps.MarkerImage(
'marker.png',
new google.maps.Size(32, 31),
new google.maps.Point(0, 0),
new google.maps.Point(16, 31)
);
var lat = record.data.latitude;
var lon = record.data.longitude;
console.log(lat,lon);
var destinationMarker = new google.maps.Marker({
icon: markerImage,
position: new google.maps.LatLng(lat,lon),
title : 'destination',
map: map,
})
var latSrc = localStorage.getItem('lat');
var lonSrc = localStorage.getItem('lon');
var sourceMarker = new google.maps.Marker({
icon: markerImage,
position: new google.maps.LatLng(latSrc,lonSrc),
title : 'source',
map: map,
})
function dir_callback(a,b){
g=a;
route_no=0;
if(b=="OK"){
var polyarr = a.routes[route_no].overview_path;
polyline.setPath(polyarr);
polyline.setMap(map);
}
}
var dirS = new google.maps.DirectionsService();
var req = {
origin: sourceMarker.getPosition(),
destination: destinationMarker.getPosition(),
travelMode: google.maps.DirectionsTravelMode.DRIVING,
provideRouteAlternatives : true
};
dirS.route(req,dir_callback);
},
//Setting the Map
var cr = new google.maps.LatLng(lat,lon);
Ext.getCmp('LocationMap').setMapCenter(cr);
You should be able to get the map instance from your map with getMap() and then add the pointer as described in the google maps api docs:
marker.setMap(map);
You can use map.getMap() to get the google map instance and use it when you create markers.
Here, you have directly added icon image path, instead use MarkerImage object as follow,
var imageIcon = new google.maps.MarkerImage(
"point.png",
new google.maps.Size(32, 32),
new google.maps.Point(0, 0),
new google.maps.Point(16, 31)
);
var marker = new google.maps.Marker({
map: map._map,
position: new google.maps.LatLng(bookletMarker[i].location[1],bookletMarker[i].location[0]),
title : bookletMarker[i].title,
draggable:false,
icon: imageIcon
});