is it possible to create a 3D polyline over a QML Map? - qt

I am trying to plot the flight trajectory of an airplane using QML maps.
Map {
[...]
MapPolyline {
[...]
path: [
{ latitude: ..., longitude: ..., altitude: 0},
.
.
.
.
{ latitude: ..., longitude: ..., altitude: 10000 }
]
}
}
Unfortunately the plotted line is flat (2D) and does not show the change in elevation.
Is it possible to plot a polyline over QML maps in 3D ?

Related

How to plot scattered point of NDVI and draw the trend in google earth engine

I am using 'USGS Landsat 8 Level 2, Collection 2, Tier 1' Landsat to calculate mean NDVI and plot the trend from the scattered plot.
I have used the following code:
For importing file:
var imageCollection 'USGS Landsat 8 Level 2, Collection 2, Tier 1'
var Table 'the shapefile'
// Define a function that will add an NDVI band to a Landsat 8 image.
var addNDVI = function(image) {
var ndvi = image.normalizedDifference(['SR_B5', 'SR_B4']).rename('NDVI');
return image.addBands(ndvi);
};
function add_NDVI_collection(image_IC){
var NDVI_IC = table.map(addNDVI);
return NDVI_IC;
}
// Filter and map the function over the collection.
var withNDVI = imageCollection.filterDate('2015-01', '2015-12')
.map(addNDVI); // <-- map() the function over the collection.
// Filter and map the function over the collection.
// Make a chart.
var chart = ui.Chart.image.series({
imageCollection: withNDVI.select('NDVI'),
region: table, //again, here the ROI is a single point
reducer: ee.Reducer.mean()})
// Define custom options for the chart. See:
// https://developers.google.com/chart/interactive/docs/reference
var options = {
title: 'NDVI over time',
hAxis: { title: 'time' ,format: 'YYYY-MMM',gridlines:{count:12}},
vAxis: { title: 'NDVI' },
series: {
0: { color: 'blue' }
}
};
// Set the options of the chart and print it.
chart = chart.setOptions(options);
print(chart); // Put it in the console
I got the following plot:
How can I plot the scattered point instead of the connecting line for the NDVI and draw the trend by removing outlier?
You can use this tutorial to have full control over your chart.
For smoothing your curve:
.setOptions({
curveType: 'function'
})
For showing the points
{
pointSize: 10
}

How to use geographic coordinate with Echarts graph?

I'm trying to use a geographic coordinate with Echarts graph. For example, the graph example given on the website are as follows: [here is the example link about the graph][1]
[![example graph][2]][2]
the data format is as follows:
{
"nodes":[
{
"id":"0",
"name":"Myriel",
"symbolSize":19.12381,
"x":-266.82776,
"y":299.6904,
"value":28.685715,
"category":0
},
{
"id":"1",
"name":"Napoleon",
"symbolSize":2.6666666666666665,
"x":-418.08344,
"y":446.8853,
"value":4,
"category":0
}],
"links":[
{
"source":"1",
"target":"0"
},
{
"source":"2",
"target":"0"
}]}
The document says I can use geographic coordinate with geoIndex to assign the corresponding geographic coordinate components.So I constructed my own graph data which is as follows:
tmp = {
"nodes":[
{
"id":0,
"name":"A",
"x":106.715912,
"y":29.510934,
"value":2.7493110918413546,
"category":0
},
{
"id":1,
"name":"B",
"x":106.375811,
"y":29.242566,
"value":2.4366801109834597,
"category":1
},
{
"id":2,
"name":"C",
"x":106.628127,
"y":29.318595,
"value":1.0339437768234796,
"category":1
},
{
"id":3,
"name":"D",
"x":106.297996,
"y":29.512318,
"value":0.7788528349157652,
"category":0
}
],
"links":[
{
"source":"0",
"target":"1"
},
{
"source":"0",
"target":"2"
},
{
"source":"1",
"target":"2"
},
{
"source":"1",
"target":"3"
}
],
"categories":[
{
"name":"SectionA"
},
{
"name":"SectionB"
}
]
};
Then, I add the corresponding attribute coordinateSystem:'geo',while it does not work. When I comment out this line,it shows like as follows. However, the positional relationship between these points is not as shown in the figure.
[![my graph][3]][3]
So,
[1]: https://echarts.apache.org/examples/zh/editor.html?c=graph
[2]: https://i.stack.imgur.com/gVQeP.png
[3]: https://i.stack.imgur.com/iDNty.png

ngx-charts line chart, how to show the line chart with dot for the data point all the time

for ngx-charts line chart, it show the line chart, but there is no dot for the data point.
If you hover the data point, it show a dot for the data pint and also with a label tooltip.
I like to have the line chart to show all the data point with a dot all the time like this.
I need your help on how to show a dot at the data point in ngx-charts line chart
Here is the sample for ngx-chart https://github.com/kedmenecr/cinnamon-angular5-with-ngx-charts
Here is the source code for ngx-chart libary . https://github.com/swimlane/ngx-charts
thanks.
if anyone still needs this feature I workaround this feature with a non-super clean solution but it works with no side effect so far :
custom service to draw the points over liner chart:
import { Injectable } from '#angular/core';
#Injectable()
export class CustomLinerChartService {
/**
* custom: override SVG to have the dots display all the time over the liner chart
* since it's not supported anymore from ngx chart
*/
showDots(chart) {
let index = 0;
const paths = chart.chartElement.nativeElement.getElementsByClassName(
'line-series'
);
const color = chart.chartElement.nativeElement.getElementsByClassName(
'line-highlight'
);
for (let path of paths) {
const chrtColor = color[index].getAttribute('ng-reflect-fill');
const pathElement = path.getElementsByTagName('path')[0];
const pathAttributes = {
'marker-start': `url(#dot${index})`,
'marker-mid': `url(#dot${index})`,
'marker-end': `url(#dot${index})`
};
this.createMarker(chart, chrtColor, index);
this.setAttributes(pathElement, pathAttributes);
index += 1;
}
}
/**
* create marker
*
*/
createMarker(chart, color, index) {
const svg = chart.chartElement.nativeElement.getElementsByTagName('svg');
var marker = document.createElementNS(
'http://www.w3.org/2000/svg',
'marker'
);
var circle = document.createElementNS(
'http://www.w3.org/2000/svg',
'circle'
);
svg[0].getElementsByTagName('defs')[0].append(marker);
marker.append(circle);
const m = svg[0].getElementsByTagName('marker')[0];
const c = svg[0].getElementsByTagName('circle')[0];
const markerAttributes = {
id: `dot${index}`,
viewBox: '0 0 10 10',
refX: 5,
refY: 5,
markerWidth: 5,
markerHeight: 5
};
const circleAttributes = {
cx: 5,
cy: 5,
r: 5,
fill: color
};
m.append(circle);
this.setAttributes(m, markerAttributes);
this.setAttributes(c, circleAttributes);
}
/**
* set multiple attributes
*/
setAttributes(element, attributes) {
for (const key in attributes) {
element.setAttribute(key, attributes[key]);
}
}
}
and after your view init and the data is set to the chart call :
#ViewChild('chart') chart: any;
ngAfterViewInit() {
this.customLinerChartService.showDots(this.chart);
}
make sure to have the reference on your chart :
<ngx-charts-line-chart #chart>
UPDATE
you can't rely on ng-reflect-fill class since it just added in development mood so insted provide your colors as array and chose it based on index for example
This simpler approach first posted here also works well:
https://github.com/swimlane/ngx-charts/issues/462#issuecomment-783237600
I suggest first getting a reference to the chart, and looping through the series:
#ViewChild("numberChart", {read: ElementRef, static: false})
numberChartRef: ElementRef;
...
chartRef.nativeElement.querySelectorAll("g.line-series path").forEach((el) => {
el.setAttribute("stroke-width", "10");
el.setAttribute("stroke-linecap", "round");
});
I test the length of the series, and only apply these changes if the length is 1. Also make sure to return the attributes to the defaults though if you don't want extra thick lines for all your charts-
I have a way simpler solution to this, just adding a single field will do the trick for you:
In your component class, set the "dot" property of the series to true:
this.data = [
{
name: 'Series 1',
series: [
{
name: 'Point 1',
value: 9,
},
{
name: 'Point 2',
value: 7,
},
{
name: 'Point 3',
value: 5,
}
],
dot: true
},
{
name: 'Series 2',
series: [
{
name: 'Point 1',
value: 8,
},
{
name: 'Point 2',
value: 6,
},
{
name: 'Point 3',
value: 4,
}
],
dot: true
}
];
This will show dots on the line chart on the respective data points as shown below:
Data points
Highlight Single Point

Openlayers 3 Reproject EPSG:4326 vector to EPSG:3857

I am needing to transform GeoJSON vector data from EPSG:4326 to EPSG:3857...
I have a map...
var olMapDiv = document.getElementById('olmap');
control.map = new ol.Map({
target: olMapDiv,
renderer: 'canvas',
layers: layers,
interactions: ol.interaction.defaults({
altShiftDragRotate: false,
dragPan: false,
rotate: false
}).extend([new ol.interaction.DragPan({ kinetic: null })]),
pixelRatio: 1,
loadTilesWhileAnimating: true,
loadTilesWhileInteracting: true,
view: view
});
and a view...
var view = new ol.View({
// make sure the view doesn't go beyond the 22 zoom levels of Google Maps
maxZoom: 21,
projection: 'EPSG:3857',
center: [0, 0],
zoom: 0
});
I define my geoJson Object...
var geoJsonObj = {
'type': 'Feature',
'geometry': JSON.parse(shape),
'name': 'V',
'id': V.vID
}
I try to read the features into a open layers Vector object and provide projection parameters...
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geoJsonObj, {defaultDataProjection:"EPSG:4326",featureProjection:"EPSG:3857"})
});
Then I use the "vectorSource" above in a new Vector layer...
vectors = new ol.layer.Vector({
title: V.vID,
source: vectorSource,
id: V.vID,
name: 'V',
label: response.VList[key].Acres,
fill: response.VList[key].Shade,
stroke: defaultStrokeHex,
style: function (feature, resolution) {
var text = resolution * 100000 < 10 ? response.VList[key].Acres : '';
if (text != "") {
styleCache[text] = [new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#319FD3',
width: 1
}),
text: new ol.style.Text({
font: '12px Calibri,sans-serif',
text: text,
fill: new ol.style.Fill({
color: '#000'
}),
stroke: new ol.style.Stroke({
color: '#fff',
width: 3
})
}),
fill: new ol.style.Fill({
color: rcisWebMapUtilities.convertHex(response.VList[key].Shade, '0.5')
})
})];
}
else if (text == "") {
styleCache[text] = [new ol.style.Style({
fill: new ol.style.Fill({
color: rcisWebMapUtilities.convertHex(response.VList[key].Shade, '0.5')
})
})
]
} return styleCache[text];
}
});
No matter what I do I either see the vector drawn...but in EPSG:4326 or nothing loads...
I've spent way too much time trying to figure out how to get OpenLayers3 to do this...Any help is greatly appreciated!!
If you use EPSG:4326 in your view then your geojson vector declaration should be
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
dataProjection: 'EPSG:4326',
featureProjection:'EPSG:4326' })
});
If you use EPSG:3857 in your view use this:
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject, {
dataProjection: 'EPSG:4326',
featureProjection:'EPSG:3857' })
});
Just to explain dataProjection is the source coords. Means the epsg of your coordinates within the geojson file. While featureProjection is the EPSG of your view and thus the EPSG of your map. Means is the EPSG original coords should be trasformed.
So try to remember this rule: featureProjection and ol.View projection declaration should be equal.
Note that I am assuming your geojson coords are projected in EPSG:4326.

The `bounds` parameter in `angular-google-map` not working?

See this DEMO
In the document, I saw the description of bounds parameter is:
Fit the map in the specified bounds. The expression must resolve to an
object having both northeast and southwest properties. Each of those
properties must have a latitude and a longitude properties
I set the bounds in scope:
$scope.bd = {
northeast: {
latitude: 51.219053,
longitude: 4.404418
},
southwest: {
latitude: -51.219053,
longitude: -4.404418
}
}
And used it in directive like this:
<ui-gmap-google-map bounds="bd" center="map.center" zoom="map.zoom" draggable="true" options="options"></ui-gmap-google-map>
But it seems that there is no effect.. the map is not fitted in my specified bounds.. Does that mean the bounds parameter is not working? And how to make the map to fit the specified bounds?
Why not using center and zoom instead of bounds ?
Anyway, I was doing some tests and as the center, zoom and bounds are in a whatch inside a directive, those are loaded async, and as the center and zoom are required the bounds are not efected.
Even setting the value after it didn't change ( don't know why )
http://plnkr.co/edit/YdyYIiVVgApA2tpm11Xn?p=preview
setTimeout(function(){
var map = $scope.instance.getGMap();
console.log(map);
console.log(map.getBounds());
$scope.bd = {
northeast: {
latitude: 51.219053,
longitude: 4.404418
},
southwest: {
latitude: -51.219053,
longitude: -4.404418
}
}
ne = new google.maps.LatLng($scope.bd.northeast.latitude, $scope.bd.northeast.longitude);
sw = new google.maps.LatLng($scope.bd.southwest.latitude, $scope.bd.southwest.longitude);
bounds = new google.maps.LatLngBounds(sw, ne);
map.fitBounds(bounds);
}, 2000);

Resources