Struggling with Nativescript Geolocation Plugin - geolocation

When using the nativescript geolocation plugin in a semi rural area, the results are wildly inaccurate, sometimes as much as 500 meters away. The results always place me at the nearest urban development rather than in the field in which I am stood. This does not happen when I am in a fully urbanised ennvironment, where results are always perfect. The field in which I walk is the highest point in my area, with phone mast arrays aplenty, so I am unsure why these results occur.
To me, the results are somehow coming from screwed up phone signal triangulation and distant wifi signals. I have tried to eradicate this by de-activating my sim card to use GPS only, but then NOTHING is returned. This suggests that GPS is not working, and I am relying on wifi and phone signal data for positioning, but as I am trying to develop an app for use in areas of poor phone signal, GPS only positioning is vital (and, at around 20 meters accuracy in most cases - perfectly acceptable for my purposes).
function buttonGetLocationTap(args) {
var location = geolocation.getCurrentLocation({
desiredAccuracy: accuracy.any,
updateDistance: 0,
maximumAge: 5000,
timeout: 5000
// desiredAccuracy: 1
// , updateDistance: 10
// , minimumUpdateTime: 600000
// , maximumAge: 600000
// , timeout: 5000
}).
then(function(loc) {
if (loc) {
var match = 'n';
var z = '';
for (var i = 0; i < x.markers.length; i++) {
var names = x.markers[i].name;
var items = x.markers[i].coordinates;
var targetLatitude = (items.latitude);
var targetLongitude = (items.longitude);
var currentLatitude = (loc.latitude.toFixed(4));
var currentLongitude = (loc.longitude.toFixed(4));
var targetLatitudelow=targetLatitude -0.0005;
var targetLatitudehigh=targetLatitude +0.0005;
var targetLongitudelow=targetLongitude -0.0005;
var targetLongitudehigh=targetLongitude +0.0005;
if (currentLatitude >= targetLatitudelow && currentLatitude <= targetLatitudehigh) {
if (currentLongitude >= targetLongitudelow && currentLongitude <= targetLongitudehigh) {
match = 'y';
z = JSON.stringify(names);
console.log(z);
page.bindingContext = {
username: z
}
}
}
else
{
match = 'n';
z = currentLatitude + currentLongitude;
console.log(z);
page.bindingContext = {
username: z
}
}
;
if (match =='y') { break; }
}
}
I would expect the same result in the semi rural area as the urbanised, am clearly have two problems:
1.Why is GPS only not working
2.Despite GPS not working - why are the results of wifi and phone signal data so wildly inaccurate when I am stood next to a mobile phone mast in the middle of a field??
Any help would be much appreciated!!

Set desiredAccuracy to Accuracy.high
Your location deceleration would then become as follows:
var location = geolocation.getCurrentLocation({
desiredAccuracy: Accuracy.high,
updateDistance: 0,
maximumAge: 5000,
timeout: 5000
})

Related

Emgucv cannot train more than 210 images using EigenFaceRecognizer it stop writing new details or data

Good day everyone I am relatively new to OpenCV using .net wrapper Emgucv my program is simple face detection and recognition, first I train user faces, at least 20 images of 100x100pixel per user and write (EigenFaceRecognizer) the data to yml files, then load this files(user images and data in yml) before running real time recognition or comparing, it worked perfectly fine with 9 user (9x20 = 180 images). However when i try to register or train another user I notice the (EigenFaceRecognizer) stop writing the data in yml. How do we solve this? The format of my data with yml extension below
opencv_eigenfaces:
threshold: .Inf
num_components: 10
mean: !!opencv-matrix
rows: 1
cols: 4096
dt: d
data: []
The trainingData.yml https://www.dropbox.com/s/itm58o24lka9wa3/trainingData.yml?dl=0
I figure it out the problem is just not enough time in writing the data so I need to increase the delay.
private async Task LoadData()
{
outputBox.Clear();
var i = 0;
var itemData = Directory.EnumerateFiles("trainingset/", "*.bmp");
var enumerable = itemData as IList<string> ?? itemData.ToList();
var total = enumerable.Count();
_arrayNumber = new int[total];
var listMat = new List<Mat>();
foreach (var file in enumerable)
{
var inputImg = Image.FromFile(file);
_inputEmGuImage = new Image<Bgr, byte>(new Bitmap(inputImg));
var imgGray = _inputEmGuImage.Convert<Gray, byte>();
listMat.Add(imgGray.Mat);
var number = file.Split('/')[1].ToString().Split('_')[0];
if (number != "")
{
_arrayNumber[i] = int.Parse(number);
}
i++;
processImg.Image = _inputEmGuImage.ToBitmap();
outputBox.AppendText($"Person Id: {number} {Environment.NewLine}");
if (total == i)
{
fisherFaceRecognizer.Train(listMat.ToArray(), _arrayNumber);
fisherFaceRecognizer.Write(YlmPath);
// FaceRecognition.Train(listMat.ToArray(), _arrayNumber);
// FaceRecognition.Write(YlmPath);
MessageBox.Show(#"Total of " + _arrayNumber.Length + #" successfully loaded");
}
await Task.Delay(10);
}
}

Printing in Openlayers 3 (pdf)

I have made a printing tools for openlayers 3 which prints in PDF format. Here is my code to print in pdf.
var dims = {
a0: [1189, 841],
a1: [841, 594],
a2: [594, 420],
a3: [420, 297],
a4: [297, 210],
a5: [210, 148]
};
var exportElement = document.getElementById('export-pdf');
exportElement.addEventListener('click', function(e) {
if (exportElement.className.indexOf('disabled') > -1) {
return;
}
exportElement.className += ' disabled';
var format = document.getElementById('format').value;
var resolution = document.getElementById('resolution').value;
var buttonLabelElement = document.getElementById('button-label');
var label = buttonLabelElement.innerText;
var dim = dims[format];
var width = Math.round(dim[0] * resolution / 25.4);
var height = Math.round(dim[1] * resolution / 25.4);
var size = /** #type {ol.Size} */ (map.getSize());
var extent = map.getView().calculateExtent(size);
map.once('postcompose', function(event) {
//var tileQueue = map.getTileQueue();
// To prevent potential unexpected division-by-zero
// behaviour, tileTotalCount must be larger than 0.
//var tileTotalCount = tileQueue.getCount() || 1;
var interval;
interval = setInterval(function() {
//var tileCount = tileQueue.getCount();
//var ratio = 1 - tileCount / tileTotalCount;
//buttonLabelElement.innerText = ' ' + (100 * ratio).toFixed(1) + '%';
//if (ratio == 1 && !tileQueue.getTilesLoading()) {
clearInterval(interval);
buttonLabelElement.innerText = label;
var canvas = event.context.canvas;
var data = canvas.toDataURL('image/jpeg');
var pdf = new jsPDF('landscape', undefined, format);
pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
pdf.save('map.pdf');
map.setSize(size);
map.getView().fitExtent(extent, size);
map.renderSync();
exportElement.className =
exportElement.className.replace(' disabled', '');
// }
}, 100);
});
map.setSize([width, height]);
map.getView().fitExtent(extent, /** #type {ol.Size} */ (map.getSize()));
map.renderSync();
}, false);
I can print in PDF when I have only OSM Layer but when I add local layers from my geoserver I can't print anything and the whole application is freezed.
Can anyone tell me what am I doing wrong here?
I am using jspdf to print pdf.
AJ
Your problem is that you load imagery from other domains, and haven't configured them for CORS. See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for a description on cross origin image use.
In order to get data out of the canvas, all images put into it must be from the same domain or transmitted with the appropriate Access-Control-Allow-Origin header.
I would investigate how to set up your server to serve the map imagery with those headers. You should also take a look at the crossOrigin option on your ol3 sources.
There is few solutions for CORS.
Very simple solution is to proxy OSM requests through your backend server (user <-> backend <-> OSM), but then we have little more server load.

Highcharts - Keep Zero Centered on Y-Axis with Negative Values

I have an area chart with negative values. Nothing insanely different from the example they give, but there's one twist: I'd like to keep zero centered on the Y axis.
I know this can be achieved by setting the yAxis.max to some value n and yAxis.min to −n, with n representing the absolute value of either the peak of the chart or the trough, whichever is larger (as in this fiddle). However, my data is dynamic, so I don't know ahead of time what n needs to be.
I'm relatively new to Highcharts, so it's possible I'm missing a way to do this through configuration and let Highcharts take care of it for me, but it's looking like I'll need to use Javascript to manually adjust the y axis myself when the page loads, and as new data comes in.
Is there an easy, configuration-driven way to keep zero centered on the Y axis?
I ended up finding a way to do this through configuration after digging even further into the Highcharts API. Each axis has a configuration option called tickPositioner for which you provide a function which returns an array. This array contains the exact values where you want ticks to appear on the axis. Here is my new tickPositioner configuration, which places five ticks on my Y axis, with zero neatly in the middle and the max at both extremes :
yAxis: {
tickPositioner: function () {
var maxDeviation = Math.ceil(Math.max(Math.abs(this.dataMax), Math.abs(this.dataMin)));
var halfMaxDeviation = Math.ceil(maxDeviation / 2);
return [-maxDeviation, -halfMaxDeviation, 0, halfMaxDeviation, maxDeviation];
},
...
}
I know this is an old post, but thought I would post my solution anyway (which is inspired from the one macserv suggested above in the accepted answer) as it may help others who are looking for a similar solution:
tickPositioner: function (min, max) {
var maxDeviation = Math.ceil(Math.max(Math.abs(this.dataMax), Math.abs(this.dataMin)));
return this.getLinearTickPositions(this.tickInterval, -maxDeviation, maxDeviation);
}
You can do this with the getExtremes and setExtremes methods
http://api.highcharts.com/highcharts#Axis.getExtremes%28%29
http://api.highcharts.com/highcharts#Axis.setExtremes%28%29
example:
http://jsfiddle.net/jlbriggs/j3NTM/1/
var ext = chart.yAxis[0].getExtremes();
Here is my solution. The nice thing about this is that you can maintain the tickInterval.
tickPositioner(min, max) {
let { tickPositions, tickInterval } = this;
tickPositions = _.map(tickPositions, (tickPos) => Math.abs(tickPos));
tickPositions = tickPositions.sort((a, b) => (b - a));
const maxTickPosition = _.first(tickPositions);
let minTickPosition = maxTickPosition * -1;
let newTickPositions = [];
while (minTickPosition <= maxTickPosition) {
newTickPositions.push(minTickPosition);
minTickPosition += tickInterval;
}
return newTickPositions;
}
Just in case someone is searching,
One option more. I ended up in a similar situation. Follows my solution:
tickPositioner: function () {
var dataMin,
dataMax = this.dataMax;
var positivePositions = [], negativePositions = [];
if(this.dataMin<0) dataMin = this.dataMin*-1;
if(this.dataMax<0) dataMax = this.dataMax*-1;
for (var i = 0; i <= (dataMin)+10; i+=10) {
negativePositions.push(i*-1)
}
negativePositions.reverse().pop();
for (var i = 0; i <= (dataMax)+10; i+=10) {
positivePositions.push(i)
}
return negativePositions.concat(positivePositions);
},
http://jsfiddle.net/j3NTM/21/
It is an old question but recently I have had the same problem, and here is my solution which might be generalized:
const TICK_PRECISION = 2;
const AXIS_MAX_EXPAND_RATE = 1.2;
function setAxisTicks(axis, tickCount) {
// first you calc the max from the data, then multiply with 1.1 or 1.2
// which can expand the max a little, in order to leave some space from the bottom/top to the max value.
// toPrecision decide the significant number.
let maxDeviation = (Math.max(Math.abs(axis.dataMax), Math.abs(axis.dataMin)) * AXIS_MAX_EXPAND_RATE).toPrecision(TICK_PRECISION);
// in case it is not a whole number
let wholeMaxDeviation = maxDeviation * 10 ** TICK_PRECISION;
// halfCount will be the tick counts on each side of 0
let halfCount = Math.floor(tickCount / 2);
// look for the nearest larger number which can mod the halfCount
while (wholeMaxDeviation % halfCount != 0) {
wholeMaxDeviation++;
}
// calc the unit tick amount, remember to divide by the precision
let unitTick = (wholeMaxDeviation / halfCount) / 10 ** TICK_PRECISION;
// finally get all ticks
let tickPositions = [];
for (let i = -halfCount; i <= halfCount; i++) {
// there are problems with the precision when multiply a float, make sure no anything like 1.6666666667 in your result
let tick = parseFloat((unitTick * i).toFixed(TICK_PRECISION));
tickPositions.push(tick);
}
return tickPositions;
}
So in your chart axis tickPositioner you may add :
tickPositioner: function () {
return setAxisTicks(this, 7);
},

How can I detect the number of lit faces on a mesh?

I have a number of objects arranged in a THREE.scene, and I want to calculate or retrieve a relative value indicating how much light each object is receiving from a single PointLight source. Simplified example:
With the light positioned at the camera, Block 1's value might be 0.50 since 3 of 6 faces are completely exposed, while 2 is ~0.33 and 3 is ~1.67.
I could probably do this the hard way by drawing a ray from the light toward the center of each face and looking at the intersects, but I'm assuming it's possible to directly retrieve the light level of each face.
This code takes the object's global matrix in consideration.
var amount = 0;
var rotationMatrix = new THREE.Matrix4();
var vector = new THREE.Vector3();
var centroid = new THREE.Vector3();
var normal = new THREE.Vector3();
for ( var i = 0; i < objects.length; i ++ ) {
var object = objects[ i ];
rotationMatrix.extractRotation( object.matrixWorld );
for ( var j = 0; j < object.geometry.faces.length; j ++ ) {
var face = object.geometry.faces[ j ];
centroid.copy( face.centroid );
object.matrixWorld.multiplyVector3( centroid );
normal.copy( face.normal );
rotationMatrix.multiplyVector3( normal );
vector.sub( light.position, centroid ).normalize();
if ( normal.dot( vector ) > 0 ) amount ++;
}
}
I think something like this should do the trick.
var amount = 0;
var faces = mesh.geometry.faces;
for ( var i = 0; i < geometry.faces.length; i ++ ) {
if ( geometry.faces[ i ].normal.dot( light.position ) > 0 ) amount ++;
}
(Warning: Brute force method!)
I'm including this for reference since it's what I'm currently using to meet all of the requirements described in the question. This function considers a face unlit if its center is not directly visible from the light's position.
I have no rotation matrix to consider for my application.
function getLightLevel(obj) {
/* Return percentage of obj.geometry faces exposed to light */
var litCount = 0;
var faces = obj.geometry.faces;
var faceCount = faces.length;
var direction = new THREE.Vector3();
var centroid = new THREE.Vector3();
for (var i=0; i < faceCount; i++) {
// Test only light-facing faces (from mrdoob's first answer).
if (faces[i].normal.dot(light.position) > 0) {
centroid.add(obj.position, faces[i].centroid);
direction.sub(centroid, light.position).normalize();
// Exclude face if centroid is obscured by another object.
var ray = new THREE.Ray(light.position, direction);
var intersects = ray.intersectObjects(objects);
if (intersects.length > 0 && intersects[0].face === faces[i]) {
litCount ++;
}
}
}
return litCount / faceCount;
}

How to assemble an array(s) of continuous points for a contour line using Conrec

I have a Conrec nightmare. I am trying to implement contour lines in ActionScript using Conrec. I have looked at both the java and javascript implementation and am still stuck. These are found here: http://paulbourke.net/papers/conrec/
Conrec will take grid data and assemble continuous contour lines. The problem is that it does not necessarily draw those lines in a continuous fashion. For example, it will draw A->B and then C->B and then C->D instead of A, B, C, D, etc.
The javascript implementation seems to be accounting for this and serializing the instructions into an array of draw points. Which is what I too want to accomplish in the end. That is it takes the instructions from the core Conrec logic (eg: A->B, C->B, C->D, etc) and organizes it into an A, B, C, D series. I think it will also return the series as a multi-dimensional array to accommodate broken lines (eg: [[A, B, C, D], [E, F, G]]). This last functionality is what I need to do in Actionscript.
This last part is where I am stuck. Ignore Conrec for now (I have given up on finding an Actionscript implementation), how can I organize these instructions into a collection of serial points? When Conrec gives me "draw point from X->Y" how can I first check if X or Y are already in a series and append either X or Y (whichever is not in the series) into the series? AND if neither are in the series, start a NEW series with X, Y as the starting set. Then check subsequent instructions against all existing series and connect series if they now start and stop on the same point? Also, I need to be able to allow for a series to close itself (eg: A, B, C, A) -- a loop (is that even possible?!).
I hope this makes sense. I'm not sure if there is a technical term for what I want to do beyond "concatenation". I also hope someone out there has done this with Conrec and can give me some pointers.
In the meantime, I am going to continue to plug away at this and see if I can come up with something but I am not confident in my abilities. I would really be thankful for some veteran or professional advice.
PS:
If you know another way to draw contour lines from grid data, I am open to alternatives. But I have to be able to implement it in Actionscript.
Ok, here is my first attempt at getting what I need done. I am not terribly happy with the result, but it seems to work.
package {
import flash.display.Sprite;
public class lineSeriesPointConcat extends Sprite {
public function lineSeriesPointConcat() {
init();
}
//directions [X -> Y]
//case 1: both counterclockwise, result is counterclockwise
private var case1:Array = [
["G1", "F1"],
["F1", "E1"],
["D1", "C1"],
["C1", "B1"],
["B1", "A1"],
["E1", "D1"], //link
["G1", "A1"] //loop
];
//case 2: clockwise, counterclockwise, result is clockwise
private var case2:Array = [
["E2", "F2"],
["F2", "G2"],
["D2", "C2"],
["C2", "B2"],
["B2", "A2"],
["E2", "D2"], //link
["G2", "A2"] //loop
];
//case 3: both clockwise, result is clockwise
private var case3:Array = [
["E3", "F3"],
["F3", "G3"],
["A3", "B3"],
["B3", "C3"],
["C3", "D3"],
["E3", "D3"], //link
["G3", "A3"] //loop
];
//case 4: counterclockwise, clockwise, result is clockwise
private var case4:Array = [
["G4", "F4"],
["F4", "E4"],
["A4", "B4"],
["B4", "C4"],
["C4", "D4"],
["E4", "D4"], //link
["G4", "A4"] //loop
];
private var collectedSeries:Array = [];
private function init():void {
var directions:Array = case1.concat(case2.concat(case3.concat(case4)));
for each (var direction:Array in directions) {
connect(direction[0], direction[1]);
}
trace ("final series:\n\t" + collectedSeries.join("\n\t"));
}
private function connect(from:String, to:String):void {
var series:Array;
var seriesStart:String;
var seriesEnd:String;
var seriesIndex:int;
var n:int = collectedSeries.length;
var i:int;
for (i = 0; i < n; i++) {
series = collectedSeries[i];
seriesStart = series[0];
seriesEnd = series[series.length - 1];
if (seriesStart == to) {
seriesStart = from;
series.unshift(from);
break;
} else if (seriesStart == from) {
seriesStart = to;
series.unshift(to);
break;
} else if (seriesEnd == to) {
seriesEnd = from;
series.push(from);
break;
} else if (seriesEnd == from) {
seriesEnd = to;
series.push(to);
break;
}
}
if (i == n) {
//this is a new series segment
series = [from, to];
seriesStart = from;
seriesEnd = to;
collectedSeries.push(series);
}
for (var j:int = 0; j < n; j++) {
var compareSeries:Array = collectedSeries[j];
if (compareSeries == series) {
//don't compare the series to itself.
continue;
}
var compSeriesStart:String = compareSeries[0];
var compSeriesEnd:String = compareSeries[compareSeries.length - 1];
if (compSeriesStart == compSeriesEnd) {
//this series loops on itself, it will not concatenate further
continue;
}
if (compSeriesStart == seriesEnd) {
trace ("case 1");
series = series.concat(compareSeries.slice(1));
} else if (compSeriesStart == seriesStart) {
trace ("case 2");
series = compareSeries.reverse().concat(series.slice(1));
} else if (compSeriesEnd == seriesStart) {
trace ("case 3");
series = compareSeries.concat(series.slice(1));
} else if (compSeriesEnd == seriesEnd) {
trace ("case 4");
series = compareSeries.concat(series.reverse().slice(1));
} else {
//no linkage between these two series
continue;
}
collectedSeries[i] = series; //replace one of the two segements
collectedSeries.splice(j, 1); //splice out the other
break;
}
trace ("series: " + series + (i == n ? " new" : ""));
}
}
}
This will give the following results:
A1,G1,F1,E1,D1,C1,B1,A1
G2,A2,B2,C2,D2,E2,F2,G2
G3,A3,B3,C3,D3,E3,F3,G3
G4,A4,B4,C4,D4,E4,F4,G4
I would still really appreciate any advice/feedback I can get. Does no one use Conrec?!
Edit: woops! I had a bug with the original splice()! sorry! fixed now
I just ported ConRec to Actionscript3 and seems to work fine, I haven't tested it thoroughly,
but it draws my contours the way I expect. Try it out if you will, I'm curious if it's a correct port. it's here:
http://www.jvanderspek.com/DEV/ConRec/ConRec.as
Ok, so there may be a much better alternative for Flash. I just found this link and it looks impressive. If this works, it obviates the original problem...
isolining package for ActionScript 3

Resources