Using trimble maps, i'm creating a route with origin and destination points given by latitude and longitude. The user can put new stops at the interactive map. The problem is that when the library returns me the stops locations, it is giving me those like X and Y and not like longitude and latitude.
For example, if the origin is
Latitude: 37.66427
Longitude: -97.72388
The application is returning me the point like
x: -10878572.558428662
y: 4532106.384744367
I'm doing this to get the stops:
var routeElements = routingLayer.getRouteElements("MyRoute");
var numberOfStops = routeElements.stops.length;
for (var i = 0; i < numberOfStops; i++) {
console.log("Stop " + i);
console.log("Lon: " + routeElements.stops[i].geometry.x);
console.log("Lat: " + routeElements.stops[i].geometry.y);
}
As says at the following documentation:
https://developer.trimblemaps.com/trimble-maps/1.2/docs/routing/
I need to know the way to convert X and Y to Longitude and Latitude or get directly the LonLat with any specific command.
You'd have to use the transform function to change the point back to a geographic projection.
In this case you would need to call
routeElements.stops[i].transform(map.getProjectionObject(),new ALKMaps.Projection("EPSG:4326"))
to get a Point object where the x and y are longitude and latitude values.
It's basically the reverse of what's described here: https://developer.trimblemaps.com/trimble-maps/1.2/docs/getting-started/spherical-mercator/
Related
Is there a way of converting a Latitude and Longitude value into a place name and then being able to display that name on a HTML page?
if ('geolocation' in navigator) {
let watchID = navigator.geolocation.watchPosition(position => {
let latitude = position.coords.latitude;
let longitude = position.coords.longitude;
console.log(latitude, longitude);
}, error => {
console.log(error.code);
}, {
enableHighAccuracy: true
});
console.log(watchID);
} else {
console.log("Not Supported");
}
The code can return the latitude and longitude and they can be displayed, I want to get the specific place if possible and display it on the page or record it in a table?
Basically, you need three things:
A list of places with their coordinates. That's sort of out of scope for this site.
A distance function. You can either use the cosine rule or haversine rule for that.
A nearest neighbour algorithm that's better than O(n). For that, you can e.g. partition your set from 1, google "sphere triangular tesselation" for that, and then you can optimize your nearest neighbour algorithm.
I'm developing a job board type website for a client that has filters for the jobs posted. This website is built off of Wordpress and using the Ajax Load More plugin to dynamically populate the jobs. I want to have a filter that a user can enter their address and the closest jobs to that entered address would populate.
I currently have it set up to grab the latitude and longitude of each job posted, as well as, the latitude and longitude of the address when the user enters it, using the Google Maps API. What I can't figure out his how to correlate the two and have Ajax Load More populate the jobs with the closest lat/long to the entered address?
First, create an array that contains the lat/lng's of the job posted. Here's an example:
var job_locs = [ //job locations array
{lat:59.611975, lng:16.547017},//within radius
{lat:59.612186, lng:16.544901},//within radius
{lat:59.614412, lng:16.538992},//within radius
{lat:59.615677, lng:16.546703},//within radius
{lat:59.618794, lng:16.545480},//within radius
{lat:59.622650, lng:16.558984},//outside radius
{lat:59.615612, lng:16.555962},//outside radius
{lat:59.610812, lng:16.549959},//outside radius
{lat:59.608804, lng:16.541045},//outside radius
{lat:59.608084, lng:16.537515},//outside radius
];
As you can see there, I have provided 5 within the 500 meter radius of the user and another 5 outside the radius. Here's the user's location:
var user = { lat: 59.615911, lng: 16.544232 };
Now you just have to loop through the array of job locations and check if they are within the radius. To do this, there is a post about this here in SO: Check if a latitude and longitude is within a circle google maps
if you check the accepted answer (credits to Guffa), he used this function to check if the point is within the radius:
function arePointsNear(checkPoint, centerPoint, km) { // credits to user:69083
var ky = 40000 / 360;
var kx = Math.cos(Math.PI * centerPoint.lat / 180.0) * ky;
var dx = Math.abs(centerPoint.lng - checkPoint.lng) * kx;
var dy = Math.abs(centerPoint.lat - checkPoint.lat) * ky;
return Math.sqrt(dx * dx + dy * dy) <= km;
}
Now we use this function in a loop:
job_locs.forEach(function(locs){
var n = arePointsNear(user, locs, 0.5); //0.5km = 500meters
if(n){
marker = new google.maps.Marker({
map: map,
position: locs,
label: {
text:"I", //marking all jobs inside radius with I
color:"white"
}
});
}else{ //remove this to see only the locations within radius
marker = new google.maps.Marker({
map: map,
position: locs,
label: {
text:"O", //marking all jobs outside radius with O
color:"white"
}
});
}
});
Note: This displays all the nearby locations from the list within the
provided radius. If there are no location found within the radius,
there will be no result. Also, please read the source of
arePointsNear function,
for the limitation of this function.
Here is a working sample in JS Bin: click me!
What You Have
Latitude/Longitude of each job
Latitude/Longitude of user's address
What You Want
List of job post displaying by nearest location
Approach
Calculate the distance using formula in this page
Load list of jobs by the order of distance calculated
I am working on something to blacklist unwanted locations with the location service. Here is my current code:
How can I implement a blacklist feature?
if (navigator.geolocation) {
// Locate position
navigator.geolocation.getCurrentPosition(displayPosition, errorFunction);
} else {
alert('Your device location is not approved.');
}
// Success callback function
function displayPosition(pos) {
var mylat = pos.coords.latitude;
var mylong = pos.coords.longitude;
var thediv = document.getElementById('locationinfo');
alert('Your HWID is compliant of ProtoProt regulations.');
}
function errorFunction(pos) {
alert('Error: (PROTOPROT_POS_DENIED). We only use your HWID for checking compliance. Enable location to enter.');
}
Maintain a list of locations given by two points w,y.
Each w,y represent the two opposite points of a w,x,y,z square which represents the blacklisted location.
Each point has longitude and latitude coordinates, so w = [long, lat] and y = [long, lat]
With those, you can rebuild all the [long, lat] of all the w,x,y,z corners of your square, thus representing the blacklisted area.
Now, it's rather easy to know the boundaries of forbidden location: any point [long, lat] which is within the square is blacklisted.
You can store those values within a Javascript Object (a dictionary) which can be stored in a distinct ".js" file. JSON representation could look like:
blacklisted_areas = {
'area 51' : [w, y], // Replace w y with the floats of long and lat
'pink unicorn zoo' : [w, y], // same
// etc.
};
Access:
long = blacklisted_area['area 51'][0]
I have a list with 50 items:
var mylocations = [{'id':'A', 'loc':[-21,2]},...,];
How can I in leaflet or JavaScript most efficiently make it such that if I accept an input of a specific location [<longitude>,<latitude>], a radius (e.g. 50 miles)... I can get all of the "mylocations" that fall within that circle?
Using external libraries is fine.
Leaflet's L.LatLng objects include a distanceTo method:
Returns the distance (in meters) to the given LatLng calculated using the Haversine formula.
http://leafletjs.com/reference.html#latlng-distanceto
var inRange = [], latlng_a = new L.LatLng(0, 0), latlng_b;
locations.forEach(function (location) {
latlng_b_ = new L.LatLng(location.pos[0], location.pos[1]);
if (latlng_a.distanceTo(latlng_b) < 80.4672) {
inRange.push(location);
}
});
What i have done so far:
i'm developing an application where i have to display more than(50K) points/Markers on the Navteq map divided into different segments.
for example: if i have 50K points i will divide all points into different segments.
if i divide 50K points into 50 segments each segment would have 1000 points (may not be 50 segments , it may depend).
right now it is working but it takes long time and hangs to render all the points on the MAP.so that i would like to perform segmentation displaying to display only few points with clustering.
so that i can get an idea of how the segment will look like.
but the problem here is i should only perform the clustering based on the segments.otherwise points from different segments willbe mixed together and displayed
as single unit and that conveys the wrong information to the user.
so here my question is: is it possible to perform the clustering based on the segment. so that only points from same segment will be clustered.
Note: if this is not possible, i would like to use Latest version of here-maps 2.5.3 (Asynchronous) may reduce some time while loading, so that i would like to use indexing functionality also while rendering the points
to improve the rendering time using nokia.maps.clustering.Index class.
i studied that indexing would reduce the time while rendering the points/markers on map. does it help in my case? could anybody please suggest how to perform indexing ?
This is the code with which i'm displaying points on map:
function displayAllLightPoints(arrLightPointCoordinats, totalLightPoints,
selectedSegmentId, totalSegmentsCount,segmentColorcode)
{
var MyTheme1 = function () {
};
segmentColorcode = segmentColorcode.substring(2,segmentColorcode.length-1);
MyTheme1.prototype.getNoisePresentation = function (dataPoint) {
var markerLightPoint = new nokia.maps.map.Marker(dataPoint, {
icon: new nokia.maps.gfx.BitmapImage("..//Images//Lightpoint//" +
segmentColorcode + ".png"),
anchor: {
x: 12,
y: 12
}
});
return markerLightPoint;
};
MyTheme1.prototype.getClusterPresentation = function (data) {
var markerLightPoint = new
nokia.maps.map.StandardMarker(data.getBounds().getCenter(), {
icon: new nokia.maps.gfx.BitmapImage("..//Images//
Segment/" + segmentColorcode + ".png", null, 66, 65),
text: data.getSize(),
zIndex: 2,
anchor: {
x: 12,
y: 12
}
});
return markerLightPoint;
};
var ClusterProvider = nokia.maps.clustering.ClusterProvider,
theme = new MyTheme1(),
clusterProvider = new ClusterProvider(map, {
eps: 0.00000000001,
minPts: 1000000,
strategy: nokia.maps.clustering.ClusterProvider.
STRATEGY_DENSITY_BASED,
theme: theme,
dataPoints: []
});
var lightpointsDataSet1 = new Array();
for (var i = 0; i < totalLightPoints; i++) {
lightpointsDataSet1[i] = { latitude: arrLightPointCoordinats[i][0],
longitude: arrLightPointCoordinats[i][1], title:
'LightPoint ' + (i + 1) };
}
clusterProvider.addAll(lightpointsDataSet1);
clusterProvider.cluster();
}
To deal with a very large (50K+) data set , I would do all the heavy number crunching server side and send over a new JSON response whenever the map is updated. Something like the HTML page described here
The key section of the code is the ZoomObserver:
var zoomObserver = function (obj, key, newValue, oldValue) {
zoom = newValue;
if (zoom < 7)
{ zoom = 7;}
if (zoom > 16)
{ zoom = 16;}
// Define the XML filename to read that contains the marker data
placeMarkersOnMaps('http://api.maps.nokia.com/downloads/java-me/cluster/'+ zoom + '.xml'
+ '?lat1=' + map.getViewBounds().topLeft.latitude
+ '&lng1='+ map.getViewBounds().topLeft.longitude
+ '&lat2='+ map.getViewBounds().bottomRight.latitude
+ '&lng2='+ map.getViewBounds().bottomRight.longitude);
};
map.addObserver("zoomLevel", zoomObserver );
Where the REST service returns a "well-known" data format which can be used to add markers and clusters to the map.
Now assuming you have two massive data sets you could make two requests to different endpoints, or somehow distinguish which cluster of data belongs to which so that you would just be returning information of the form:
{latitude':51.761,'longitude':14.33128,'value':102091},
i.e. using the DataPoint standard (which means you could use a heat map as well.
Of course, what I'm not showing here is the back-end functionality to cluster in the first place - but this leaves the client (and the API) to do what it does best displaying data, not number crunching.