create arrow using leafletjs - javascript

I want to create a arrow in leaflet using poly lines of multipolylines whichever suits..
The arrow class should take in following param
baselatitude = base of the arrow where the arrow will be on map
baselongitude = base of the arrow where the arrow will be on map
pointlatitude = the tip of the arrow on the map
pointlongitude = the tip of the arrow on the map
apointlatitude
apointlongitude
bpointlatitude
bpointlongitude
angle = rotation degree
can anyone please provide guidance on creating the arrow using following param . It would be nice to if you can create a leaflet class extension L.arrow

did that myself for fit my requirement .. pasting in if somebody finds it useful someday
feature.geometry.coordinates[0] is the geoJson collection where all the coordinates are retrieved
L.Playback.WindArrowMarker = L.Marker.extend({
initialize: function (startLatLng, options, feature) {
this._min = 99;
this._max = 0;
this._arrowStyleOptions = [
{ color: '#ffff00' },
{ color: '#00ffff' },
{ color: '#00ff00' }];
var ArrowData = feature.geometry.coordinates[0];
var ArrowBaseLon = ArrowData[0];
var ArrowBaseLat = ArrowData[1];
var ArrowPointLat = ArrowData[2];
var ArrowPointLon = ArrowData[3];
var ArrowPointALat = ArrowData[4];
var ArrowPointALon = ArrowData[5];
var ArrowPointBLat = ArrowData[6];
var ArrowPointBLon = ArrowData[7];
var ArrowHeight = ArrowData[8];
var ArrowMagnitude = ArrowData[9];
var ArrowBearing = ArrowData[10];
if (ArrowMagnitude > this._max) this._max = ArrowMagnitude;
if (ArrowMagnitude < this._min) this._min = ArrowMagnitude;
var styleToUse=this._getArrowStyle(ArrowMagnitude);
//Create Arrow structure and assign first value from the playback data
//baseLtlg //PointLtlg
this._arrowbase = L.polyline([[ArrowBaseLat, ArrowBaseLon], [ArrowPointLat, ArrowPointLon]], styleToUse);
//PointLtlg //PointAtLtlg
this._arrowpointA = L.polyline([[ArrowPointLat, ArrowPointLon], [ArrowPointALat, ArrowPointALon]], styleToUse);
//PointLtlg //PointBLtlg
this._arrowpointB = L.polyline([[ArrowPointLat, ArrowPointLon], [ArrowPointBLat, ArrowPointBLon]], styleToUse);
//Call leaflet marker initialization to attach this as marker
L.Marker.prototype.initialize.call(this, [ArrowBaseLat, ArrowBaseLon], {});
//Calculate windspeed
var windspeed = this._calculateWindspeed(ArrowMagnitude, feature.modeldata.Adder, feature.modeldata.Multiplier)
//Attach a popup
this._arrowbase.bindPopup(this.getPopupContent(ArrowBearing, windspeed));
},
_calculateWindspeed: function (magnitude, adder, multiplier) {
return (magnitude - parseFloat(adder)) / multiplier
},
_getArrowStyle: function (magnitude) {
this._arrowMagMed = 7;
this._arrowMagHigh = 10;
if (magnitude > this._arrowMagHigh)
styleToUse = this._arrowStyleOptions[2];
else if (magnitude > this._arrowMagMed)
styleToUse = this._arrowStyleOptions[1];
else
styleToUse = this._arrowStyleOptions[0];
return styleToUse;
},
getPopupContent: function (bearing, windspeed) {
return sprintf("Wind blowing from: %s deg(from North)<br> Wind Speed(m/s): %s", bearing.toFixed(1), windspeed.toFixed(1));
},
addTo: function (map) {
this._arrowbase.addTo(map);
this._arrowpointA.addTo(map);
this._arrowpointB.addTo(map);
},
move: function (windData,transitionTime, modelData) {
var ArrowBaseLon = windData[0];
var ArrowBaseLat = windData[1];
var ArrowPointLat = windData[2];
var ArrowPointLon = windData[3];
var ArrowPointALat = windData[4];
var ArrowPointALon = windData[5];
var ArrowPointBLat = windData[6];
var ArrowPointBLon = windData[7];
var ArrowHeight = windData[8];
var ArrowMagnitude = windData[9];
var ArrowBearing = windData[10];
var styleToUse = this._getArrowStyle(ArrowMagnitude);
//Assign color based on magnitude
this._arrowbase.setStyle(styleToUse);
this._arrowpointA.setStyle(styleToUse);
this._arrowpointB.setStyle(styleToUse);
//Set Base,Apoint,Bpoint LatLongs as they are the ones changing
this._arrowbase.setLatLngs([[ArrowBaseLat, ArrowBaseLon], [ArrowPointLat, ArrowPointLon]])
this._arrowpointA.setLatLngs([[ArrowPointLat, ArrowPointLon], [ArrowPointALat, ArrowPointALon]])
this._arrowpointB.setLatLngs([[ArrowPointLat, ArrowPointLon], [ArrowPointBLat, ArrowPointBLon]])
//Calculate windspeed
var windspeed = this._calculateWindspeed(ArrowMagnitude, modelData.Adder, modelData.Multiplier)
//Check if popup is attached
if (this._arrowbase._popup) {
//Set popup content while moving
this._arrowbase._popup.setContent(this.getPopupContent(ArrowBearing, windspeed));
}
}
});

It would be nice to if you can create a leaflet class extension L.arrow
No: this is not a place where people make things for you. But we can Google things, like Leaflet arrow which leads you directly to Leaflet.PolylineDecorator.

Related

How do i can add custom html tags in am-chart (map-chart)

I am trying to add custom html <a href="state/alaseka"><a> on each state of america as shown in map example out put would be something like this site "https://covidactnow.org/?s=1311324" and i am trying this as follow
Javascript
am4core.ready(function() {
function am4themes_myTheme(target) {
if (target instanceof am4core.ColorSet) {
target.list = [
am4core.color("#ff3b37")
];
}
}
// Themes begin
am4core.useTheme(am4themes_myTheme);
// Themes end
// Create map instance
var chart = am4core.create("usstatemap", am4maps.MapChart);
// Set map definition
chart.geodata = am4geodata_usaLow;
// Set projection
chart.projection = new am4maps.projections.AlbersUsa();
var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
// Create map polygon series polygonSeries
//Set min/max fill color for each area
polygonSeries.heatRules.push({
property: "fill",
target: polygonSeries.mapPolygons.template,
min: chart.colors.getIndex(1).brighten(-0.3),
max: chart.colors.getIndex(1).brighten(1)
});
// Make map load polygon data (state shapes and names) from GeoJSON
polygonSeries.useGeodata = true;
stateName = {{ allStateName | safe }}
statePopulation = {{ allStatePopulation | safe }}
console.log("==========================act casess keyindicator3 =====================")
console.log(actcase)
var data = [];
var id = "";
var value = "";
var expenses = "";
for(var i = 0; i < stateName.length; i++){
year =actdate[i]
//e.,g "US-"+actdate[i]
id ="US-"+actdate[i];
url="http://127.0.0.1:8000/states/"+actdate[i]
value = actdeath[i];
console.log(url);
data.push({id:id, value:value,url:url});
}
console.log("==== state from us ap =======\t\t\t",data)
// Set heatmap values for each state
polygonSeries.data = data;
chart.events.on( "ready", updateCustomMarkers );
chart.events.on( "mappositionchanged", updateCustomMarkers );
// this function will take current images on the map and create HTML elements for them
function updateCustomMarkers( event ) {
// go through all of the images
polygonSeries.MapPolygon.each(function(image) {
// check if it has corresponding HTML element
if (!image.dummyData || !image.dummyData.externalElement) {
// create onex
image.dummyData = {
externalElement: createCustomMarker(image)
};
}
// reposition the element accoridng to coordinates
var xy = chart.geoPointToSVG( { longitude: image.longitude, latitude: image.latitude } );
image.dummyData.externalElement.style.top = xy.y + 'px';
image.dummyData.externalElement.style.left = xy.x + 'px';
});
}
// this function creates and returns a new marker element
function createCustomMarker( image ) {
var chart = image.dataItem.component.chart;
// create holder
var holder = document.createElement( 'a' );
holder.className = 'map-marker';
holder.title = image.dataItem.dataContext.title;
holder.style.position = 'absolute';
holder.href = 'www.google.com';
holder.target = '_parent';
// maybe add a link to it?
if ( undefined != image.url ) {
holder.onclick = function() {
window.location.href = image.url;
};
holder.className += 'map-clickable';
}
}//Set up heat legend
heatLegend = chart.createChild(am4maps.HeatLegend);
heatLegend.series = polygonSeries;
heatLegend.align = "right";
heatLegend.valign = "bottom";
heatLegend.width = am4core.percent(20);
heatLegend.marginRight = am4core.percent(4);
heatLegend.minValue = 0;
heatLegend.maxValue = 400000;
// Set up custom heat map legend labels using axis ranges
var minRange = heatLegend.valueAxis.axisRanges.create();
minRange.value = heatLegend.minValue;
minRange.label.text = "min";
var maxRange = heatLegend.valueAxis.axisRanges.create();
maxRange.value = heatLegend.maxValue;
maxRange.label.text = "max";// Set up custom heat map legend labels using axis ranges
// Blank out internal heat legend value axis labels
heatLegend.valueAxis.renderer.labels.template.adapter.add("text", function(labelText) {
return "";
});
// Configure series tooltip
var polygonTemplate = polygonSeries.mapPolygons.template;
polygonTemplate.tooltipText = "{name}: {value}";
polygonTemplate.nonScalingStroke = true;
polygonTemplate.strokeWidth = 0.5;
// Create hover state and set alternative fill color
var hs = polygonTemplate.states.create("hover");
hs.properties.fill = am4core.color("#3c5bdc");
});
Note:
i have used my data you can use the data from the amchart as link mentioned bellow for dummy data to be used and i am following exactly the same chart as in the link,
https://www.amcharts.com/demos/us-heat-map/
i have resolve this question by adding this simple one line in the above code
polygonTemplate.propertyFields.url = "url";
to make this work you have to add the URL for each state into the data series object

Reduction over an image collection Google Earth Engine

I am using CHIRPS data set (daily precipitation) to derive mean, median, min and max precipitation within a certain time frame. Then, I want to extract the values at specific locations included in a point shapefile and save the results in a table.
The script seem to work but the output table only has zeros (0) as values for the 4 variables.
Please see the script below
var lng = 65.64;
var lat = 34.35;
var point = ee.Geometry.Point(lat, lng);
//var aoi = point.buffer(100000); // Create an area (1km buffer around point)
var country = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017')
.filter(ee.Filter.eq('country_co', 'AF'));
var aoi = country;
Map.setCenter(lng, lat, 5); // Center the map on this location, zoom level 10
var start = '2018-02-15'; // initial date of the image collection
var end = '2018-07-15'; //final date of the image collection
var p1 = ee.Geometry.Point([69.78086, 34.65411])
var p2 = ee.Geometry.Point([61.82234, 30.66048])
var table = ee.FeatureCollection(ee.List([ee.Feature(p1),ee.Feature(p2)]))
var AddPrMean = function(image) {
var PrMean = image.reduce(ee.Reducer.mean()).rename('PrMean');
return image.addBands(PrMean);
};
var AddPrMedian = function(image) {
var PrMedian = image.reduce(ee.Reducer.median()).rename('PrMedian');
return image.addBands(PrMedian);
};
var AddPrMin = function(image) {
var PrMin = image.reduce(ee.Reducer.min()).rename('PrMin');
return image.addBands(PrMin);
};
var AddPrMax = function(image) {
var PrMax = image.reduce(ee.Reducer.max()).rename('PrMax');
return image.addBands(PrMax);
};
var dataset = ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
.filterDate(start, end)
.filterBounds(aoi)
.map(AddPrMean)
.map(AddPrMedian)
.map(AddPrMin)
.map(AddPrMax);
var composites = dataset.select(['PrMean','PrMedian','PrMin','PrMax']).first();
var YieldLocations = ee.FeatureCollection(table);
var YPrec = composites.reduceRegions(YieldLocations, ee.Reducer.max(), 1);
print(YPrec); ```
I found a solution that seems to work, however, the median always gives 0 as result.
var lat = 34.35;
var point = ee.Geometry.Point(lat, lng);
//var aoi = point.buffer(100000); // Create an area (1km buffer around point)
var country = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017')
.filter(ee.Filter.eq('country_co', 'AF'));
var aoi = country;
Map.setCenter(lng, lat, 5); // Center the map on this location, zoom level 10
var start = '2018-02-15'; // initial date of the image collection
var end = '2018-07-15'; //final date of the image collection
var p1 = ee.Geometry.Point([69.78086, 34.65411])
var p2 = ee.Geometry.Point([61.82234, 30.66048])
var table = ee.FeatureCollection(ee.List([ee.Feature(p1),ee.Feature(p2)]))
var dataset = ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
.filterDate(start, end)
.filterBounds(aoi);
var PrMean = dataset.mean().rename('PrMean');
var PrMedian = dataset.median().rename('PrMedian');
var PrMin = dataset.min().rename('PrMin');
var PrMax = dataset.max().rename('PrMax');
var composites = PrMean
.addBands(PrMedian)
.addBands(PrMin)
.addBands(PrMax);
var YieldLocations = ee.FeatureCollection(table);
var YPrec = composites.reduceRegions(YieldLocations, ee.Reducer.max(), 1);
print(YPrec);```

Win Pivot App. Need to access some data from a section. Any ideas?

I have a JavaScript Win Pivot Application
Into the Hub I am retrieving some information:
function initPages(options) {
for (var i = 0; i < options.length ; i++) {
var menuItem = options[i];
menuItem.showBanner = (i == 0);
definePages(options);
}
}
and in a .Js file I have the definePages function created:
functions.js:
function definePages(item) {
var action = item[0];
var animation = item[1];
var scyfy = item[2];
var localmovies = item[3];
var clasic = item[4];
var comedy = item[5];
var biography = item[6];
var drama = item[7];
var kids = item[8];
var musical = item[9];
var romantic = item[10];
var suspense = item[11];
var horror = item[12];
var art = item[13];
var personalities = item[14];
var history = item[15];
var society = item[16];
}
Now, in my section 1 I initialize the page by calling another function there:
ready: function (element, options) {
// TODO: Inicializar la página aquí.
options = options || {};
initMovies();
},
function initMovies() {
var element = document.getElementById("movieContainer");
//var movies = ??????????????????????????
//console.log(movies);
//it keeps going
}
I need to be able to retrive, in that var movies, the var action, from the functions.Js or, which is the same, the items[0]...
However, if I call a function in functions.Js, which is defined in section1Page, it won´t work...
I can call functions and pass data from anywhere to functions.Js, but not the other way around...
Any ideas on what should I do? Thanks!!!
I fixed it... I created a global var in function.Js and I get the info from the array in each section later on:
function definePages(item) {
tooSleepyToThink = item;
}
section1Page:
function initMovies() {
var elemento = document.getElementById("movieContainer");
console.log(tooSleepyToThink[0].text);
}

Map circle markers unique content onclick

I'm trying to give each marker/shape on leaflet different information for onClick. The data I'm using is from a JSON array filled with objects.
The code I used to do this is:
var map = L.map('map').setView([43.16556, -77.61139], 13);
var OpenStreetMap_DE = L.tileLayer('http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', {
attribution: '©>'
}).addTo(map);
//Adding a circle. (point[long,Lat], radius in meters
// Saving for later :-)
// var zip = "/javascripts/zcta5.json",
// hsa = "/javascripts/hsa.json";
var host = new Array();
var temp;
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
$.getJSON("/allHospitals",function(data,status){
var color;
var thefill;
for (var i = 0; i < data.length; i++) {
temp = data[i];
if (temp.name === "rgh") {
color = '#FF9755';
thefill = '#009666';
} else if (temp.name === "strong") {
color = '#FFE03A';
thefill = '#7C83FF';
}
host.push(L.circle(data[i].lnglat, data[i].pplNum/2, {
color: color,
fillColor: thefill,
fillOpacity: 1,
weight:3
}));
host[i].on("click", onClick);
host[i].addTo(map);
}
});
var svg = d3.select(map.getPanes().overlayPane).append("svg"),
g = svg.append("g").attr("class", "leaflet-zoom-hide");
function onOver(e){
}
function onClick (e) {
console.log(temp);
}
It returns the last entry in the json file. How can I just make this work?
function onClick (e) {
console.log(temp);
}
You want to be looking at e not temp. e is what was clicked, temp is just leftover from the loop above.

Bing Maps - removing Itinery icons

I'm tryng to create a route planner to track my running routes. Using Bing Maps, I am able to create the route, but I'm struggling to remove to default 'beginning', 'end' and 'red circle' itinery icons.
Below is my code so far (based on this link). All I basically want is my own start icon at the beginning of the route and my end icon at the end. I don't need anything else in between apart from the route line.
Any help (along with code improvement tips) gratefully received!
jQuery(function() {
GetMap();
$("#btnStartRoute").click(function() {
map.AttachEvent('onclick', StartRouting);
});
});
var map = null;
var myRoute = [];
var noOfPushPins = 0;
function GetMap() {
map = new VEMap('mapContent');
map.SetCredentials("xxxxxxxxxxxxxxxxxx");
map.LoadMap();
}
function StartRouting(e) {
var xPoint = e.mapX, yPoint = e.mapY;
var pixel = new VEPixel(xPoint, yPoint);
var LL = map.PixelToLatLong(pixel);
cornerOne = LL; //cornerOne is a global level var
var latitude = map.PixelToLatLong(pixel).Latitude;
var longitiude = map.PixelToLatLong(pixel).Longitude;
myRoute[noOfPushPins] = new VELatLong(latitude, longitiude);
noOfPushPins++;
GetRoute();
}
function GetRoute() {
var myRouteOptions = new VERouteOptions();
myRouteOptions.RouteMode = VERouteMode.Walking;
myRouteOptions.RouteColor = new VEColor(0, 102, 51, .7);
myRouteOptions.RouteCallback = RouteCallback;
map.GetDirections(myRoute, myRouteOptions);
}
function RouteCallback(route) {
var myRouteShapes = [];
var myRoutePoints = [];
var points = route.RouteLegs[0].Itinerary.Items;
$.each(points, function(i) {
var routePointCoordinates = new VELatLong(route.RouteLegs[0].Itinerary.Items[i].LatLong.Latitude, route.RouteLegs[0].Itinerary.Items[i].LatLong.Longitude);
var routePointShape = new VEShape(VEShapeType.Pushpin, routePointCoordinates);
if (i != 0) {
routePointShape.SetCustomIcon("<img id='pushPin" + noOfPushPins + "' class='pushPin' src='/Content/Images/Maps/pushPinEnd.gif'><span class='pushPinText'>" + (noOfPushPins + 1) + "</span>");
} else {
routePointShape.SetCustomIcon("<img id='pushPin" + noOfPushPins + "' class='pushPin' src='/Content/Images/Maps/pushPinStart.gif'><span class='pushPinText'>" + (noOfPushPins + 1) + "</span>");
}
myRoutePoints.push(routePointShape);
map.Clear();
map.DeleteRoute();
map.AddShape(myRoutePoints);
});
}
There's an un-documented property called "Shape" on the Itinerary object. You can hide it...
More info here: http://social.msdn.microsoft.com/Forums/en/vemapcontroldev/thread/430449d0-fde4-4adb-9132-248fa6f9db65

Categories