Map Route Direction Zoom to Segment - javascript

Basically I am trying to zoom to certain route segment when getting direction on OneMap. Here is the JavaScript codes where I trying to plot a route and zoom to certain route segment:
function getDirections() {
var routeData = new Route;
var from = document.getElementById('txtFrom').value
var to = document.getElementById('txtTo').value
//Draw out the line from the cordinate to another cordinate
routeData.routeStops = from + ";" + to;
//What type of mode will it do
routeData.routeMode = "DRIVE";
//can draw out untill the following coordiante
routeData.barriers = '36908.388637,35897.420831';
{
if (document.getElementById('CbAvoid').checked) {
routeData.avoidERP = "1";
}
else
routeData.avoidERP = "0";
}
routeData.GetRoute(showRouteData)
}
function showRouteData(routeResults) {
if (routeResults.results == "No results") {
alert("No Route found, please try other location.")
return
}
$('#divComputedDirection').show();
directions = routeResults.results.directions[0];
directionFeatures = directions.features;
var routeSymbol = new esri.symbol.SimpleLineSymbol().setColor(new dojo.Color([0, 0, 255, 0.5])).setWidth(4);
var mergedGeometry = new esri.geometry.Polyline()
mergedGeometry.addPath(routeResults.results.routes.features[0].geometry.paths[0])
OneMap.map.graphics.add(new esri.Graphic(mergedGeometry, routeSymbol));
//Display the total time and distance of the route
var htmlStr = "";
htmlStr += "<img class='close-image' onclick='closeDirectionResultDIV();' alt='close' src='img/closeDirectionResult.png' />";
htmlStr += "<span style='font-weight:bold;'><br /> Total distance: " + Math.round(directions.summary.totalLength) + "km" + "<br /> Total time: " + Math.round(directions.summary.totalTime) + "mins <br/></span>";
document.getElementById("divComputedDirection").innerHTML = htmlStr;
//List the directions and create hyperlinks for each route segment
for (var i = 0; i < directions.features.length; i++) {
var feature = directions.features[i]
document.getElementById("divComputedDirection").innerHTML += '<br>' + parseInt(parseInt(i) + 1) + ". " + feature.attributes.text + " (" + formatDistance(feature.attributes.length, "miles") + ", " + formatTime(feature.attributes.time) + ") " + '';
}
}
//Zoom to the appropriate segment when the user clicks a hyperlink in the directions list
function zoomToSegment(index) {
var segment = directionFeatures[index];
map.setExtent(segment.geometry.getExtent(), true);
if (!segmentGraphic) {
segmentGraphic = map.graphics.add(new esri.Graphic(segment.geometry, segmentSymbol));
}
else {
segmentGraphic.setGeometry(segment.geometry);
}
}
It did plot the route and show all the directions. But when I click on certain direction and zoom to segement, it throws me an error message which is Uncaught TypeError: Cannot call method 'getExtent' of undefined.
I wonder why is it so. Thanks in advance.

The root cause of your error is that you're trying to get the extent of a .geometry property that doesn't exist - that part is relatively easy. The problem, I think, is that you're looking for the geometry of each segment of the journey, and the return from OneMap's RouteTask doesn't give you that directly.
The geometry from the entire route is in
routeResults.results.routes.features[0].geometry.paths[0]
and the individual segments are in one of ESRI's fun compressed formats in the value:
routeResults.results.directions[x].features[y].compressedGeometry
There's some documentation and C# code for this compressed format here:
http://resources.esri.com/help/9.3/arcgisengine/ArcObjects/esrinetworkanalyst/INACompactStreetDirection_CompressedGeometry.htm
It should be relatively easy to port that C# code to JS if you really need the geometry of individual segments.
OneMap have a full working example here which shows how to process the results from the RouteTask, but unfortunately they don't attempt to extract the compressedGeometry field.
Edit: More sample code from ESRI here, with examples in C#/Java/Python.

Related

The prototype is returning my function instead of the return value

I want to create the subtitle of my pages similar to the image
And I want to do this by calling my prototype from main.js
Vue.prototype.subtitlePage = function () {
var path = this.$route.path;
var array_path = path.split('/');
var subtitle = "<ul class='subtitle'>";
var index;
for (index = 1; index < array_path.length - 2; index++) {
subtitle += "<li>" + array_path[index] + "</li> >>";
}
subtitle += "<li>" + array_path[index] + "</li><ul>";
return subtitle;
}
I'm calling my function that way in the construction of my screen
<p class="indextitle">Subir Nova Redação</p>
<p v-html="subtitlePage"></p>
However the text that appears on the screen is not the html return mounted in the function, but the code of my function
function () { var path = this.$route.path; var array_path = path.split('/'); var subtitle = "
"; var index; for (index = 1; index < array_path.length - 2; index++) { subtitle += "
" + array_path[index] + "
>>"; } subtitle += "
" + array_path[index] + "
"; return subtitle; }
Does anyone know what I'm doing wrong and what I have to change in my code to appear in the subtitle what I set up in the function?
v-html expects a string, while a function is given, this results in stringified function output. It should be:
<p v-html="subtitlePage()"></p>
This should never be done in practice with user-defined data.
Dynamically rendering arbitrary HTML on your website can be very dangerous because it can easily lead to XSS attacks. Only use v-html on trusted content and never on user-provided content.
URL is user-defined data here. It can be tailored by a culprit to evaluate arbitrary JS on user side.
A correct way to do this is to create a component for a breadcrumb and output it with:
<li v-for="pathSegment in pathSegments">{{pathSegment}}</li>
In case a segment may contain URL-encoded symbols (spaces and non-ASCII characters in this example), segments need to be additionally transformed with decodeURIComponent (this isn't covered in original code and will be a primary hazard for v-html).
I managed to do it as follows
Vue.mixin({
computed: {
subtitlePage: {
get: function () {
var path = this.$route.path;
var array_path = path.split('/');
var subtitle = "<ul class='subtitle'>";
var index;
for (index = 1; index < array_path.length - 2; index++) {
subtitle += "<li>" + array_path[index] + "</li> >>";
}
subtitle += "<li>" + array_path[index] + "</li><ul>";
return subtitle;
}
}
}
})

Counting Photoshop Clipping Path Points

I am trying to make a Javascript script that gives me an alert of how many clipping paths there are in the file and how much anchor points it has. (If the clipping path is too complex InDesign will crash on some computers in our environment)
I found in the Scripting Guide the object PathPoint and PathPointInfo, but I can't seem to get it to work.
What I made so far is this
// pathCount
// enable double clicking from the Macintosh Finder or the Windows Explorer
#target photoshop
// in case we double clicked the file
app.bringToFront();
var activeDoc = app.activeDocument;
var totalPathItemCount = activeDoc.pathItems.length;
//myPathItem.subPathItems.length;
var myPathItem = activeDoc.pathItems.getByName("CLIPPING");
var mySubPathItem = myPathItem.subPathItems;
var clippingPathPointCount = myPathItem.pathPoints.length;
alert("There are " + totalPathItemCount + " paths and CLIPPING has " + clippingPathPointCount " points " );
Loop over each subPathItem using a for statement and add the count of anchor points (i.e. for each subPathItem) to the clippingPathTotalAnchorCount variable. For example:
#target photoshop
app.bringToFront();
var activeDoc = app.activeDocument;
var totalPathItemCount = activeDoc.pathItems.length;
// Specifically for the path named "CLIPPING"...
var myPathItem = activeDoc.pathItems.getByName("CLIPPING");
var mySubPathItems = myPathItem.subPathItems;
var mySubPathItemCount = mySubPathItems.length;
// Loop over each subpath of the path named "CLIPPING".
// The count of anchor points for each subpath are added to the total.
var clippingPathTotalAnchorCount = 0;
for (var i = 0; i < mySubPathItemCount; i++) {
clippingPathTotalAnchorCount += mySubPathItems[i].pathPoints.length;
}
alert("The document has " + totalPathItemCount + " path(s).\r" +
"The path named CLIPPING has " + mySubPathItemCount + " subpaths,\r" +
"with a total of " + clippingPathTotalAnchorCount + " anchor points.");
//Index the item in teh collection with [0]
var mySubPathItem = myPathItem.subPathItems[0];

How to make clickable line in JQuery Flot?

I am using flot to make line charts. One of the functionality I am trying to implement is highting the line (including points on the line and its corresponding legend), if the user clicks on the line, cancel the highlighting if the user clicks anywhere else on the chart.
Tried 'plotclick' event, but it requires clicking on points. I need the ability to get the series when clicking on the line as well.
Hopefully, there is a way to do that.
You have to manually search for the nearest point on the line and then calculate the distance with something like this:
$('#placeholder').on('plotclick', function(event, pos, item) {
$('#output').empty();
if (item) { // clicked on point
$('#output').text('series: ' + item.series.label + ' - datapoint: ' + item.dataIndex);
return;
}
else { // search for line
for (var i = 1; i < data.length; i++) {
if (data[i-1][0] <= pos.x && pos.x < data[i][0]) {
var lineX = (pos.x - data[i-1][0]) / (data[i][0] - data[i-1][0]);
var lineY = data[i-1][1] + lineX * (data[i][1] - data[i-1][1]);
if (Math.abs(pos.y - lineY) < maxDistance) {
$('#output').html('between datapoints ' + (i-1) + ' and ' + i + '<br />'
+ 'distance from line: ' + Math.abs(pos.y - lineY).toFixed(3));
}
return;
}
}
}
});
See this fiddle for a full example. If you have multiple data series you can search for the nearest point on each line and then calculate the nearest line.

javascript API call results in old data

I have a weather web api,which I need to show weather report of current city in website.Whenever the code calls in the API, it results only in old data.Data never changes and when I run the web API URL on the browser it results exactly what I want.
Please help me what could be the reason for the cached data.
webAPI
http://api.openweathermap.org/data/2.5/weather?lat=26.894049&lon=80.942686&mode=json
my code
$.getJSON('http://api.openweathermap.org/data/2.5/weather?lat=' + lat + '&lon=' + lon + 'mode=json&rand=' + Math.random(), function (data) {
var wind = {};
var temp = {};
wind = data.wind;
temp = data.weather;
var clouds = '%' + data.clouds.all;
var description = data.weather[0].description;
var temp = data.main.temp - 273.15;
var humidity = data.main.humidity + '%';
var icon = data.weather[0].icon;
weatherImg = "<img height=\"45\" width=\"45\" style=\"border: medium none; width: 45px; height: 45px;position:relative;top:-10px; background: url('http://openweathermap.org/img/w/" + icon + ".png') repeat scroll 0% 0% transparent;\" alt=\"title\" src=\"http://openweathermap.org/images/transparent.png\">";
document.getElementById('weatherImg').innerHTML = weatherImg;
document.getElementById('current_temp').innerHTML = (temp) + '°C';
document.getElementById('current_wind').innerHTML = ' ; ' + wind.speed + 'Km/h';
document.getElementById('city_name').innerHTML = data.name;
});
tested your code working fine for me some time api response is slow but other than that every thing looks ok to me
htttp://jsfiddle.net/navneetccna/un2u5j0v
Shouldn't the url in your script prefix mode with &. You should throw this in a fiddle / be more specific. You say you're getting old data. Are you getting an old JSON response that doesn't change at all, or infrequently?

Using dynamic markers in a Leaflet map

I'm working on a dynamic mapping application that receives a series of data as JSON and then converts the data to a map point with a pop up in Leaflet.
The JSON data looks like this:
{
"unit":"90",
"latitude":36.120915,
"longitude":-97.0633733,
"velocity":0.022,
"heading":102.9,
"timestamp":"Wed, 23 Nov 2011 20:00:28 GMT"
}
I have a listener setup to receive this data from a push server which calls the below function to draw the unit's location on the map.
function drawUnit(unit)
{
//removeUnitMarkers();
var popupContent = "<h3>" + unit.number + "</h3>";
popupContent = popupContent + "<p><strong>Direction: </strong>" + unit.heading + "<br />";
popupContent = popupContent + "<strong>Speed: </strong>" + unit.velocity + "<br />";
popupContent = popupContent + "<strong>Last Update:</strong> " + unit.timestamp + "<br /></p>";
var markerLocation = new L.LatLng(unit.latitude,unit.longitude);
var marker = new L.Marker(markerLocation);
var unitNumber = unit.number;
var unitTest = 'test';
console.log(unitData);
unitLayerGroup.addLayer(marker);
marker.bindPopup(popupContent);
//unitMarkerCache.push(marker);
//map.panTo(markerLocation);
}
This works for a single unit but I need it to work for 2 or more units.
I'm struggling to think about what to do to draw the units on the map and be able to call a unique marker to destroy it and then redraw it. I've thought about defining an array or object to hold the data but I can't get it to work with a unit's number as part of the variable name.
var marker[unit.number] = {"unit":unit.number, "latitude":unit.latitude};
Doing something like the above var marker[unit.number] doesn't work; Firebug always throws an error:
missing ; before statement
http://10.10.1.10:86/map2.php
Line 161
This is line 161: var marker[unit.number] = new L.Marker(markerLocation);
I don't know how your eventlistener is setup, and how many unique units you have. but If you only have one unit = "90" and want to plot its location by listening to data sent from that unit, this code will work.
pointMarkers = [];
var listener = new EventSource("your event source");
listener.addEventListener('your call', function(e){
points = JSON.parse(e.data);
if(points.unit = '90') {
for (var i =0; i < pointMarkers.length; i++) {
mymap.removeLayer(pointMarkers[i]);
}
marker = L.marker([points.latitude, points.longitude]).addTo(mymap);
pointMarkers.push(marker);
}
}, false);

Categories