I want to remove route from previous calculation in HERE Maps, in my code bellow, if i do two times calculation, the new routes overlay the previous routes.
................................................................................................................................................................
function addRouteShapeToMap(route)
{
// map.removeObject(route.shape);
var strip = new H.geo.Strip(),
routeShape = route.shape,
polyline;
routeShape.forEach(function(point)
{
var parts = point.split(',');
strip.pushLatLngAlt(parts[0], parts[1]);
});
polyline = new H.map.Polyline(strip,
{
style:
{
lineWidth: 4,
strokeColor: 'rgba(0, 128, 255, 0.7)'
}
});
// Add the polyline to the map
map.addObject(polyline);
// And zoom to its bounding rectangle
map.setViewBounds(polyline.getBounds(), true);
}
and this is code for add maneuvers symbol :
function addManueversToMap(route)
{
var svgMarkup = '<svg width="18" height="18" ' +
'xmlns="http://www.w3.org/2000/svg">' +
'<circle cx="8" cy="8" r="8" ' +
'fill="#1b468d" stroke="white" stroke-width="1" />' +
'</svg>',
dotIcon = new H.map.Icon(svgMarkup,
{
anchor:
{
x: 8,
y: 8
}
}),
group = new H.map.Group(), i, j;
// Add a marker for each maneuver
for (i = 0; i < route.leg.length; i += 1)
{
for (j = 0; j < route.leg[i].maneuver.length; j += 1)
{
// Get the next maneuver.
maneuver = route.leg[i].maneuver[j];
// Add a marker to the maneuvers group
var marker = new H.map.Marker({
lat: maneuver.position.latitude,
lng: maneuver.position.longitude
},
{
icon: dotIcon
});
marker.instruction = maneuver.instruction;
group.addObject(marker);
}
}
group.addEventListener('tap', function(evt)
{
map.setCenter(evt.target.getPosition());
openBubble(
evt.target.getPosition(), evt.target.instruction);
}, false);
// Add the maneuvers group to the map
map.addObject(group);
}
than if the route success, where can i place code map.removeObject(route); in this function?
function onSuccess(result)
{
var route = result.response.route[0];
addRouteShapeToMap(route);
addManueversToMap(route);
addWaypointsToPanel(route.waypoint);
addManueversToPanel(route);
addSummaryToPanel(route.summary);
}
help me to solve my code..
This might not be the best solution, but it works for me.
Make sure to provide the same id name both for polyline and group.
Before you map.addObject(polyline), give a name for id:
polyline.id = "route";
// Add the polyline to the map
map.addObject(polyline);
Also the same do for map.addObject(group):
group.id = "route";
// Add the maneuvers group to the map
map.addObject(group);
Finally create a new function as follows:
function removeObjectById(id){
for (object of map.getObjects()){
if (object.id===id){
map.removeObject(object);
}
}
}
When you execute the function by providing id, e.g in your console browser, it will remove both polyline and maneuvers:
removeObjectById("route");
It looks like you are using this example as the basis for your code.
map.removeObject(route) won't work, because route is not an object on the map. The objects you want to remove are the group and polyline objects. To do so you probably want to change the scope of those variables by declaring them outside of the addRouteShapeToMap and addManueversToMap functions. If you declare them at the top of your code:
polyline = new H.map.Polyline(strip, {
style: {
lineWidth: 4,
strokeColor: 'rgba(0, 128, 255, 0.7)'
}
});
var group = new H.map.Group();
you can then use
map.removeObject(polyline);
map.removeObject(group);
to remove the line and markers from the map later on (for example when start another route calculation). Note that onSuccess is not the right place to add this, as the objects would be removed right after adding them, thus preventing them from ever being visible.
Make sure that before map.removeObject(polyline); polyline is set as an object when map.addObject is used.
Instead of adding the route to the map instance, add it to a group.
So here should be the steps that you should follow:
1. Create a group, and have a reference to it.
2. When you add a route, add it to the group (like this)
this.group.addObject(new this.H.map.Polyline(
lineString, { style: { lineWidth: 4 } }
));
When you want to clear the map, you can clear the group (like this)
this.group.removeAll();
I have tested this logic. it is working fine!
Related
So I have a large geojson file with about 3,000 polygons and about 10 properties each. I want to have a few buttons on the webpage that pass information into the setStyle function where I can use it to switch between which property is being used to style the map.
Here is the script block along with the two buttons.
<input id = 'Default' type ='button' value ='Default'>
<input id = 'Ranked' type ='button' value ='Ranked'>
<script>
let my_data = JSON.parse('{{ json_data | tojson | safe }}');
function initMap() {
let map = new google.maps.Map(document.getElementById('Map'), {
zoom: 8,
center: { lat: 41, lng: -78 },
});
map.data.addGeoJson(my_data);
map.data.setStyle(
function(feature){
let income = feature.getProperty('Ranked_Income');
let houses = feature.getProperty('Ranked_Houses');
let income2 = feature.getProperty('Normalized_Income');
let houses2 = feature.getProperty('Normalized_Houses');
let r, g, b = 0;
r = '00';
g = Math.round((income) * 255);
b = Math.round((1 - income) * 255);
let color = '#' + r.toString(16) + g.toString(16) + b.toString(16);
return {
fillOpacity: 0.75,
fillColor: color,
strokeWeight: 0.3,
};
}
);
}
</script>
I want a button to switch between the ranked income and the normalized income. Later on I also want to be able to select various colors, but I can't figure out how to get any outside information into that function.
So I just found a workaround. I just copied the entire map.setStyle block and controlled it with an if statement. I then reloaded the page by calling init map again.
This is likely an awful solution, if anyone has anything better please let me know.
This question (leaflet concentric circles (angular 2)) is similar, but since its not quite the same and no-one has answered it I thought I would start over.
My Leaflet map is populated by markers created in PHP from a MySql database. Here is a link if you want to see it; https://net-control.us/map1Test.php.
I would like to be able to right click on any given marker and have a series of concentric circles drawn around that marker at various distances in miles (example: 2, 5, 10, 15).
I think I need to do this with GeoJSON but any method that does what I need is OK with me. I just have not figured out how to first of all draw the circles at the distances I need and secondly how to allow a marker to be right clicked to display them.
I can't find any examples, and the only similar question has not been answered. Can someone show me how to do this? I use OSM maps.
The code (PHP) to make each marker looks like this;
$markers .= " var $callsign = new L.Marker(new L.LatLng($row[koords]),{ icon: new L.{$row[iconColor]}({number: '$rowno' }), title: \"marker_$rowno\"}).addTo(fg).bindPopup(\"$rowno<br>$row[mrkrfill]\").openPopup(); $($callsign._icon).addClass(\"$row[classColor]\"); markers.push($callsign); \n";
You don't share the code which creates the markers, so this is necessarily theoretical...
When creating the marker, add a contextmenu hook, which calls a function that uses L.circle to add circles to the map.
EDIT: So I peeked at the source of your site, your Javascript snippet for each marker should end up like this:
var WA0TJT = new L.Marker(new L.LatLng(39.202911,-94.602887),{
icon: new L.NumberedDivIcon({number: '1' }),
title:
"marker_1"}).addTo(fg).bindPopup("1<br><b>#0013</b><br>WA0TJT<br>Keith Kaiser<br>Platte Co., MO Dist: A<br>39.202911, -94.602887<br>EM29QE").openPopup().on("contextmenu", drawCircles);
$(WA0TJT._icon).addClass("bluemrkr");
markers.push(WA0TJT);
with a new function like this
function drawCircles(event e) {
L.circle(e.target.getLatLng(), {radius: <radius in metres>}).addTo(map);
// ... any more circles you need ...
}
var i;
var r = 1609.34; // in meters = 1 mile, 4,828.03 meters in 3 miles
var circleOptions = {
color: 'blue',
fillColor: '#69e',
fillOpacity: 0
}
for (i=0 ; i < 3; i++ ) {
r = (r * i) + r;
alert(lat+", "+lng);
var circle = L.circle([lat, lng], r, circleOptions);
circle.addTo(map);
r = 1609.34; // reset r so r calculation above works for each 1 mile step
}
having a very strange problem.
A: One method of my map works fine. User sets start point and end point and map is created and the fitBounds.extend(bounds) sets zoom level appropriately to encompass the start/end markers on the map.
B: The second method is if the user sets a start point but not and end point, but based on other user interests I get retrieve and end point for them and plot it on the map using the same functions as method A. However, upon fitBounds.extend(bounds) it sets the zoom level way out at 4 (country level). Then I have to force set the zoom.
It doesn't matter when at any point the user does method A (before or after method B)...when its method A, the zoom level is correct. When its method B its always to zoom level 4.
...but all using the same functions.
Both methods accurately put the markers on the map and accurately draw the route between the markers. Just on method A, the auto zoom is correct and on method B the zoom is always set to 4.
If user does A, its right...then B happens, its zooms out...does B again it stays zoomed out...does A again it goes back to proper zoom.
Driving me nuts here!
My map object is "setMap", it is a global var
function setMapBounds(start,end) {
mapBounds = new google.maps.LatLngBounds();
mapBounds.extend(start.position);
mapBounds.extend(end.position) ;
setMap.fitBounds(mapBounds) ;
}
function addMarkers(newMarkers) { // an array of map points.
var tempMarkers = [] ;
for (var x=0;x<newMarkers.length;x++) {
var tempLatlon = new google.maps.LatLng(newMarkers[x].lat,newMarkers[x].lon) ;
var tempMarker = createMarker(tempLatlon,newMarkers[x].img,newMarkers[x].title) ;
tempMarkers.push(tempMarker) ;
}
return tempMarkers ;
}
function createMarker(latlon,img,title) {
var marker = new google.maps.Marker({
map:setMap,
position:latlon,
icon: img,
title:title
}) ;
return marker ;
}
// This is Method A - it ALWAYS sets the zoom properly
function setDropoff(dropoffLoc) { //called from: index.js/setPickup(), tab-map.html
geoCoder.geocode({'address': dropoffLoc}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
endLocation = dropoffLoc ;
endLat = results[0].geometry.location.lat() ;
endLon = results[0].geometry.location.lng() ;
// first clear any existing END Markers only.
while(markersArray.length) {
markersArray.pop().setMap(null);
}
endPointSet = 1 ;
endLatlon = new google.maps.LatLng(endLat,endLon) ;
var endMarker = createMarker(endLatlon,'img/red-pin.png','Drop off') ;
markersArray.push(endMarker) ;
setMapBounds(userMarker,endMarker) ;
if (startPointSet == 1) {
drawRoute("DRIVING",startLocation,endLocation) ;
}
}
} else {
error = "Address not found."
}
});
}
// This is method B, it ALWAYS pushees the zoom out to 4. It is pulled out of another function that tests to see if the user manually set and end point...if so, then add wayPoints between user set start/end points. If not, then set map to user start point to a single end point of interest
if (endPointSet == 1) { // draw Pickup to START to wayPoints to END
var markers = [
{lat:interests[0].shub_lat,lon:interests[0].shub_lon,img:interests[0].img,title:"Pickup"},
{lat:interests[1].ehub_lat,lon:interests[1].ehub_lon,img:interests[1].img,title:"Dropoff"}
] ;
var points = [interests.shub_address,interests.ehub_address] ;
extraMarkers = addMarkers(markers) ;
drawRoute("BICYCLING",startLocation,endLocation,points) ;
} else {
var markers = [
{lat:interests[0].shub_lat,lon:interests[0].shub_lon,img:interests[0].img,title:"Dropoff"}
] ;
extraMarkers = addMarkers(markers) ;
setMapBounds(userMarker,extraMarkers[0]) ;
drawRoute("WALKING",startLocation,interests[0].shub_address) ;
}
}
Here is are the objects passed into setMapBounds from the else within Method B. Start point is set by User...but no end point is set, I am picking one for them. The first Object is start, the second object is end.
Lh {__gm: Object, gm_accessors_: Object, map: Qk, closure_uid_909815000: 563, gm_bindings_: Object…}
Lf: Object
...
position: pf
D: -82.49799999999999
k: 27.873196
...
Lh {__gm: Object, gm_accessors_: Object, map: Qk, closure_uid_909815000: 602, gm_bindings_: Object…}
Lf: Object
...
position: pf
D: -82.47631678090198
k: 27.9374560148825
...
And here are the objects passed into setMapBounds from Method A where the user is setting both the same start and end points. you can see the start point is the same for both Method A and B.
Lh {__gm: Object, gm_accessors_: Object, map: Qk, closure_uid_909815000: 563, gm_bindings_: Object…}
Lf: Object
...
position: pf
D: -82.49799999999999
k: 27.873196
...
Lh {__gm: Object, gm_accessors_: Object, map: Qk, closure_uid_909815000: 703, gm_bindings_: Object…}
Lf: Object
...
position: pf
D: -82.45717760000002
k: 27.950575
...
I am making a similar application, and the code that I am using is:
var start;
var end;
function updateMap(name, obj){ //obj is a form input i.e. <input type="text">
var marker = (name==='start')?start:end;
geocoder.geocode({address:obj.value}, function(results, status){
//get coords/check if is valid place
if(status === google.maps.GeocoderStatus.OK){
//get info, store in new marker
marker.setPosition(results[0].geometry.location);
marker.setTitle(obj.value);
//if both markers present
if(start.getPosition() && end.getPosition()){
map.fitBounds(new google.maps.LatLngBounds(start.getPosition(), end.getPosition()));
}else{
//otherwise, if one marker
map.setCenter(marker.getPosition());
map.setZoom(15);
}
marker.setMap(map);
}else if(status === google.maps.GeocoderStatus.ZERO_RESULTS){
alert('There is an issue with address. Please refer to the "Help" link.');
}else{
setTimeout(function(){
updateMap(marker, obj);
}, 200);
}
});
}
What this does is take an argument from a text input, geocode it, and place a marker on the map. The function is triggered by an onchange event on the form element. This can be easily adapted for your own usage. If there was only one point, I just settled for a default zoom value (usually pretty close to the street, though you can adjust this however you want).
As for your question of why it is not working, I can formulate a better guess with the entire code. For now, I would think it has something to do with region-biasing, or that it is simply a bug. It is probably just best to work around it.
Here is my code:
$.each(data, function (i, val) {
salesmanTrackPoints[val.id] = new Array();
var coords = new nokia.maps.geo.Coordinate(parseFloat(val.latitude), parseFloat(val.longitude));
salesmanTrackPoints[val.id] = new nokia.maps.map.Polyline(coords, {
polyline: {
pen: {
strokeColor: "#00F8",
lineWidth: 5
}
},
arrows: true
});
map.objects.add(salesmanTrackPoints[val.id]);
});
Above code is not working. Please help me if what is wrong.
To create the Polyline, you need to add the array of coordinates inside the loop, and then outside of the loop you can add a single mapobject to the Display e.g.:
var coords = [],
salesmanTrackPoints;
// Loop to add all the coordinates to an array
$.each(data, function (i, val) {
coords.push(parseFloat(val.latitude));
coords.push(parseFloat(val.longitude));
});
// Now create the Polyline
salesmanTrackPoints = new nokia.maps.map.Polyline(coords, {
pen: {
strokeColor: "#22CA",
lineWidth: 5
},
arrows: true
});
map.objects.add(salesmanTrackPoints);
Of course this may need to be altered depending upon the structure of your data. It is important to note that Polyline can take an Array of Coordinates or an Array of Numbers (as individual lat, longs) as you can see from the API Documentation.
I have a connection to a database(db). I am getting the lon, lat and name from the db and stroing them:
while ($row_ChartRS = mysql_fetch_array($sql1))
{
$latitude=$row_ChartRS['latitude'];
$longitude=$row_ChartRS['longitude'];
$bus_name =$row_ChartRS['short_name'];
//echo $latitude.'--'.$longitude.'<br>';
echo $bus_name;
I then create a map to display the data. The markers are working fine for all lat, lon locations. Code:
function init()
{
projLonLat = new OpenLayers.Projection("EPSG:4326"); // WGS 1984
projMercator = new OpenLayers.Projection("EPSG:900913"); // Spherical Mercator
overviewMap = new OpenLayers.Control.OverviewMap();
//adding scale ruler
scale = new OpenLayers.Control.ScaleLine();
scale.geodesic = true; // get the scale projection right, at least on small
map = new OpenLayers.Map('demoMap',
{ controls: [ new OpenLayers.Control.Navigation(), // direct panning via mouse drag
new OpenLayers.Control.Attribution(), // attribution text
new OpenLayers.Control.MousePosition(), // where am i?
new OpenLayers.Control.LayerSwitcher(), // switch between layers
new OpenLayers.Control.PanZoomBar(), // larger navigation control
scale,
overviewMap // overview map
]
}
);
map.addLayer(new OpenLayers.Layer.OSM.Mapnik("Mapnik"));
map.addLayer(new OpenLayers.Layer.OSM.Osmarender("Osmarender"));
//Create an explicit OverviewMap object and maximize its size after adding it to the map so that it shows
//as activated by default.
overviewMap.maximizeControl();
//Adding a marker
markers = new OpenLayers.Layer.Markers("Vehicles");
map.addLayer(markers);
vectorLayer = new OpenLayers.Layer.Vector('Routes');
map.addLayer(vectorLayer);
for (k in Locations)
{
//adding a popup for the marker
var feature = new OpenLayers.Feature(markers, new OpenLayers.LonLat(Locations[k].lon, Locations[k].lat).transform(projLonLat,projMercator));
//true to close the box
feature.closeBox = true;
feature.popupClass = new OpenLayers.Class(OpenLayers.Popup.AnchoredBubble,
{
//create the size of the box
'autoSize': true,
'maxSize': new OpenLayers.Size(100,100)
});
//add info into box
for (z in names)
{
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[z]).transform(projLonLat,projMercator));
}
//puts a scroll button on box to scroll down to txt
//feature.data.overflow = "auto";
marker = feature.createMarker();
marker.display(true);
markerClick = function (evt) {
if (this.popup == null) {
this.popup = this.createPopup(this.closeBox);
map.addPopup(this.popup);
this.popup.show();
} else {
this.popup.toggle();
}
currentPopup = this.popup;
OpenLayers.Event.stop(evt);
};
marker.events.register("mousedown", feature, markerClick);
markers.addMarker(marker);
map.setCenter(new OpenLayers.LonLat(Locations[k].lon, Locations[k].lat).transform(projLonLat,projMercator), zoom);
var lonLat1 = new OpenLayers.LonLat(Locations[k].lon,Locations[k].lat).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
var pos2=new OpenLayers.Geometry.Point(lonLat1.lon,lonLat1.lat);
points1.push(pos2);
//Uncomment to put boxes in when map opens
//feature.popup = feature.createPopup(feature.closeBox);
//map.addPopup(feature.popup);
//feature.popup.show()
}
var lineString = new OpenLayers.Geometry.LineString(points1);
var lineFeature = new OpenLayers.Feature.Vector(lineString,'',style_green);
vectorLayer.addFeatures([lineFeature]);
map.setCenter(lonLat1,zoom);
} //function
However the name in the popup marker is the same for all markers. i.e. the last name pulled from the db. Can anyone please help with this - I have spent 3 full days trying to fix it!
Thanks in advance!
A few comments:
The PHP code you’ve posted is completely irrelevant, since it’s not seen to be used anywhere.
The objects names and Locations aren’t declared anywhere in the code you posted. What do they contain?
In the code quoted below, you’re creating multiple new Feature objects, but you assign them all to the same property (thereby overwriting that property each time). Is that intentional?
//add info into box
for (z in names) {
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[z]).transform(projLonLat,projMercator));
}
Edit:
This does appear to be where it’s going wrong. You should remove the for...z loop, and replace it with the following code:
//add info into box
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[k]).transform(projLonLat,projMercator));
Since in PHP, you’re using the same index ($v) to fill both arrays, it makes sense to use the same index to read them in javascript...
Aside from that, using the for...in loop on Javascript arrays is not considered good practice, for a number of reasons. It’s better to use the following:
for (k = 0; k < Locations.length; k += 1) {
// your code
}
i had the same problem , and i solve it ...
the problem is overwrite
you don't have to loop inside your function , do the loop for function for example:
function init(z)
{
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[z]).transform(projLonLat,projMercator));
}
for (z in names)
{
init(z)
}