I am working on a project with Vue and Leaflet that for now just shows a map and I want that when you give the start and end coordinates it colours the route from between those points (or many points and a route than goes through all of them). Unfortunately, I found that the plugin for Leaflet that uses OSRM for automating routing "will not work unless you configure a routing backend yourself". Is there an alternative to that? Any other open-source plugin for Vue Leaflet (or alternatively for OpenLayers(VueLayers) that can auto-track existing routes? Thank you in advance.
You could interface Openlayers directly with a service such as OpenRouteService https://openrouteservice.org/dev/#/api-docs/v2/directions/{profile}/json/post This code assumes a map routesMap with a vector layer orsRoute, and array routeComplete of coordinate pairs in view projection for start, optional waypoint, and end, and API key orsKey
var viewProj = routesMap.getView().getProjection();
var startA = ol.proj.transform(routeComplete[0], viewProj, 'EPSG:4326');
var viaA = routeComplete[1] ? ol.proj.transform(routeComplete[1], viewProj, 'EPSG:4326') : null;
var endA = ol.proj.transform(routeComplete[2], viewProj, 'EPSG:4326');
var startN = startA.toString();
var viaN = viaA ? viaA.toString() : null;
var endN = endA.toString();
var url = 'https://api.openrouteservice.org/v2/directions/driving-car/json';
var params = '{"coordinates":[[' + startN + '],[' + (viaN ? viaN + '],[' : '') + endN + ']]}';
var orsXhr = new XMLHttpRequest();
orsXhr.onreadystatechange = function() {
if (orsXhr.readyState == 4) {
if (orsXhr.status == 200) {
var route = JSON.parse(orsXhr.responseText).routes[0];
var linestring = route.geometry;
var distance = route.summary.distance;
var duration = route.summary.duration;
orsRoute.getSource().addFeature(
new ol.Feature({
geometry: new ol.format.Polyline().readGeometry(linestring).transform('EPSG:4326', viewProj),
name: 'Openrouteservice',
distance: distance,
duration: duration
})
);
orsRoute.getSource().setAttributions('© Powered by openrouteservice');
}
}
}
orsXhr.onerror = function(e) { console.log('error'); }
orsXhr.ontimeout = function(e) { console.log('timeout'); }
orsXhr.open('POST', url, true);
orsXhr.timeout = 3000;
orsXhr.setRequestHeader('Content-type', 'application/json');
orsXhr.setRequestHeader('Authorization', orsKey);
orsXhr.send(params);
I have done a query on my feature layer and got a result. the only problem is that the resulting object doesn't contain a LAT and LNG attribute. Here is the problem:
centerAndZoomOnAsset(assetId: string) {
let query = this.pipeFL.createQuery();
query.where = `AssetId = '${assetId}'`;
query.outFields = ['*'];
this.pipeFL.queryFeatures(query).then((result: esri.FeatureSet) => {
debugger;
const foundFeatureGraphic: esri.Graphic = result.features[0];
if (foundFeatureGraphic) {
const center = foundFeatureGraphic.geometry.extent.center.clone();
At this point I have a value for center, and it has it's x,y coords, however, I do not have: center.latitude or center.longitude...
I don't see why it will not have it. When I do a hit test on a click, it contains both lat and lng, but when i query from outside of the hit test, it doesn't contain my lat and lng.
Any ideas as to why this is happening?
You need to set the returnGeometry parameter to true in order to get spatial data from the query. See the API here
Try using this:
centerAndZoomOnAsset(assetId: string) {
let query = this.pipeFL.createQuery();
query.where = `AssetId = '${assetId}'`;
query.returnGeometry = true;
query.outFields = ['*'];
this.pipeFL.queryFeatures(query).then((result: esri.FeatureSet) => {
debugger;
const foundFeatureGraphic: esri.Graphic = result.features[0];
if (foundFeatureGraphic) {
const center = foundFeatureGraphic.geometry.extent.center.clone();
Does someone know how to get weather information in Titanium? I read that the Google Weather API is no longer available. I have tried this link but I can't figure out how to put this to work.
Does someone have a working code? I would like to get the weather on my position given by longitude and latitude.
Titanium.Geolocation.getCurrentPosition(function(e) {
if (e.error) {
return;
} else {
var lon = e.coords.longitude;
var lat = e.coords.latitude;
if (Ti.Network.networkType == Ti.Network.NETWORK_NONE) {
return;
} else {
var client = Ti.Network.createHTTPClient({
onload : function(e) {
var weather = JSON.parse(this.responseText);
getweatherIcon(weather.weather[0].icon);
setweatherText(weather.weather[0].id, weather.main.temp);
},
onerror : function(e) {
},
timeout : 150000
});
client.open("GET", "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&appid=CreatedAppID");
client.send();
}
}
});
The "CreatedAppID" is the ID that I have created after creating an account on the provided link that is above.
We are trying to find suggestions, or implementation options on how to hide a marker once a new point on the map has been clicked.
In our application, once the user clicks on a particular pin on the map, we display a new pin (in a different lat/long location) that is associated with the click event. I.e. a point should be in oklahoma, but the map is displaying texas, so once the marker texas is clicked, a new marker in oklahoma is shown. Our issue is that whenever a user selects a new point, we are not able to "hide" the marker for the previous selection, which then clutters our screen.
Any suggestions on how we could handle this issue?
Code is below:
require(["esri/map", "esri/geometry/Point", "esri/symbols/SimpleMarkerSymbol", "esri/graphic", "dojo/_base/array", "dojo/dom-style", "dojox/widget/ColorPicker", "esri/InfoTemplate", "esri/Color", "dojo/dom", "dojo/domReady!", "esri/geometry/Polyline", "esri/geometry/geodesicUtils", "esri/units","esri/symbols/SimpleLineSymbol"],
function( Map, Point,SimpleMarkerSymbol, Graphic, arrayUtils, domStyle, ColorPicker, InfoTemplate, Color, dom, Polyline, geodesicUtils, Units,SimpleLineSymbol) {
map = new Map("mapDiv", {
center : [-98.35, 35.50],
zoom : 5,
basemap : "topo"
//basemap types: "streets", "satellite", "hybrid", "topo", "gray", "oceans", "osm", "national-geographic"
} );
map.on("load", pinMap);
var arr = [];
var initColor, iconPath;
function pinMap( ) {
map.graphics.clear();
iconPath = "M16,3.5c-4.142,0-7.5,3.358-7.5,7.5c0,4.143,7.5,18.121,7.5,18.121S23.5,15.143,23.5,11C23.5,6.858,20.143,3.5,16,3.5z M16,14.584c-1.979,0-3.584-1.604-3.584-3.584S14.021,7.416,16,7.416S19.584,9.021,19.584,11S17.979,14.584,16,14.584z";
var infoContent = "<b>Id</b>: ${Id} ";
var infoTemplate = new InfoTemplate(" Details",infoContent);
$.post( '{{ path( 'points' ) }}', {}, function( r ) {
arrayUtils.forEach( r.points, function( point ) {
if (point.test==1) {
initColor = "#CF3A3A";
}
else {
initColor = "#FF9900";
}
arr.push(point.id,point.pinLon1,point.pinLat1,point.pinLon2,point.pinLat2);
var attributes = {"Site URL":point.url,"Activity Id":point.id,"Updated By":point.updated,"Customer":point.customer};
var graphic = new Graphic(new Point(point.pinLon1,point.pinLat1),createSymbol(iconPath,initColor),attributes,infoTemplate);
map.graphics.add( graphic );
map.graphics.on("click",function(evt){
var Content = evt.graphic.getContent();
var storeId = getStoreId(Content);
sitePins(storeId);
});
} );
}, 'json' );
}
function getStoreId( content ){
var init = content.split(":");
var fin= init[2].split("<");
return fin[0].trim();
}
function sitePins( siteId ) {
iconPathSite = "M15.834,29.084 15.834,16.166 2.917,16.166 29.083,2.917z";
initColorSite = "#005CE6";
var infoContent = "<b>Distance</b>: ${Distance} Miles";
var infoTemplate = new InfoTemplate(" Distance to Location",infoContent);
var indexValue=0;
for (var index = 0; index < arr.length; index++){
if (arr[index]==storeId){
indexValue =index;
}
}
pinLon1 = arr[indexValue+1];
pinLat1 = arr[indexValue+2];
pinLon2 = arr[indexValue+3];
pinLat2 = arr[indexValue+4];
var line = {"paths":[[[pinLon1, pinLat1], [pinLon2, pinLat2]]]};
line = new esri.geometry.Polyline(line);
var lengths = Number(esri.geometry.geodesicLengths([line], esri.Units.MILES)).toFixed(2);
var attributes = {"Distance":lengths};
var graphicSite = new Graphic(new Point (pinLon1,pinLat1), createSymbol(iconPathSite, initColorSite),attributes,infoTemplate);
var pathLine = new esri.Graphic(line, new esri.symbol.SimpleLineSymbol());
map.graphics.add( pathLine );
map.graphics.add( graphicSite );
}
function createSymbol( path, color ) {
var markerSymbol = new esri.symbol.SimpleMarkerSymbol( );
markerSymbol.setPath(path);
markerSymbol.setSize(18);
markerSymbol.setColor(new dojo.Color(color));
markerSymbol.setOutline(null);
return markerSymbol;
}
} );
</script>
As far as I get the code, it shows the distance between the marker and the point then clicked.You are creating point and polyline on each click event on map. Following can help:
1) Please provide id say 'abc' to polyline, graphic site.
2) Then on every click event remove the graphic and polyline with id 'abc'.
dojo.forEach(this.map.graphics.graphics, function(g) {
if( g && g.id === "abc" ) {
//remove graphic with specific id
this.map.graphics.remove(g);
}
}, this);
3) Then you can create the new polyline and point as you are already doing it.
Ti.GeoLocation.forwardGeocoder() is not converting Non US address to lat and long values.
sample code below.
Ti.GeoLocation.forwardGeocoder('Hyderabad, India', function(e){
var lat = e.latitude;
var long = e.longitude;
});
with this code we are getting lat and long values are undefined.
The proper way to get US addresses, and everywhere else in the world (that Google can find) and display the Long/Lat on a titanium Map.
The code below uses the string variable: myAddress
var myAddress = address + ','+ city + ',' + postal + ',' + country //'Vieux Port, Montreal, Quebec, H2X3R4, Canada'
var xhrGeocode = Ti.Network.createHTTPClient();
xhrGeocode.setTimeout(120000);
xhrGeocode.onerror = function (e) {
alert('Google couldn\'t find the address... check your address');
};
xhrGeocode.onload = function (e) {
var response = JSON.parse(this.responseText);
if (response.status == 'OK' && response.results != undefined && response.results.length > 0) {
longitude = response.results[0].geometry.location.lng;
latitude = response.results[0].geometry.location.lat;
}
};
var urlMapRequest = "http://maps.google.com/maps/api/geocode/json?address=" + myAddress.replace(/ /g, '+');
urlMapRequest += "&sensor=" + (Ti.Geolocation.locationServicesEnabled == true);
xhrGeocode.open("GET", urlMapRequest);
xhrGeocode.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhrGeocode.send();
var addrReq = Titanium.Network.createHTTPClient();
var addrUrl = "http://maps.googleapis.com/maps/api/geocode/json?sensor=true&address="+ query;
addrReq.open("GET",addrUrl);
addrReq.send(null);
addrReq.onload = function()
{
var response = JSON.parse(this.responseText);
if(response.status == "OK"){
LT.Customlat=response.results[0].geometry.location.lat;
LT.Customlon=response.results[0].geometry.location.lng;
}
you will need to roll your own solution using google REST APIs, the underlying Titanium API does not support non-us addresses