Is it normal for the onSuccess routine from geolocation.watchPosition to update every second, even when the maximumAge is set to 0?
I detect this as followed:
The onSuccess value from compass.watchHeading is updating every 0,1 sec and showing in a div. When calling this value with document.getElementById in the onSuccess routine from geolocation.watchPosition and displaying it in a div nearby I see the value slowly updating, seems every second or so.
I need to use the heading value within the results of location, that's why I noticed.
To make it visible:
function onSuccess1(heading) {
direction = Math.round(heading.magneticHeading);
// Debug info
document.getElementById('heading').innerHTML = direction;
}
function onSuccess2(position) {
positionLat = position.coords.latitude;
positionLong = position.coords.longitude;
var direction = document.getElementById('heading').innerHTML;
// Debug info
document.getElementById('headingControle').innerHTML = direction;
}
<div id = "debug">
<span id = "heading"></span><span id = "headingControle"></span>
</div>
Related
I want to create a text typing effect in simple web application. It's my first time using dart for web application. I did something like this.
var chars = "Hello World".split('');
var textstream = Stream<String>.fromIterable(chars);
var idx = 0;
textstream.listen((data) {
Future.delayed(Duration(milliseconds: idx * 200), () {
var element = querySelector('#hero-keyword');
element.appendText(data);
idx++;
});
});
And my html has this
<p id="hero-keyword"></p>
But, I want each letter printed in the interval of 200ms. But what I got is, all letters show up at the same time.
Your idx variable is only being updated when the delayed future completes, which will happen on the first pass of the event loop after the specified delay.
fromIterable, however, will process its values all at once, in sequence. Taken together, the net effect is that all of your delays are being set to 0, and then, after a slight delay, all of your characters will be emitted, and idx will be incremented.
You can try the following pattern, instead, adjusted to your use case:
void main() {
var text = "Hello world";
Stream
.periodic(Duration(milliseconds: 200), (count) {
print(text[count]);
})
.take(text.length)
.drain();
}
I have a map, that has both new and migrated areas. The new areas are being pushed to the map, but the migrated ones are not. They are somewhat loading, as the length of the collection is correct. map.entites.push('polygon') is not working.
here is the code I am using:
var checkExist = setInterval(function () {
var counter = 0;
for (var i = 0; i < viewData.zones.length; i++) {
var zone = viewData.zones[i];
var id = zone["ID"];
var geometricArea = zone["CoverageArea"];
var geography = geometricArea["Geography"];
//console.log("geography object :" + JSON.parse(geography));
//var zoneShape = zoneShapes[i];
// console.log(geography.WellKnownText);
var polygon = WKTModule.Read(geography.WellKnownText)
polygon.shapeType = ('Polygon').toLowerCase();
polygon.id = id;
map.entities.push(polygon);
zoneEntities.push(polygon);
});
});
Also- Even though the polygon isnt being pushed to the map, the coordinates are there and it has an id. I am not sure what is happening.
Thanks!
What is the zoneEntities variable? If it is a layer/entityCollection this would cause an issue as you already tried adding the shape to the map. Which map control are you using V7 or v8. V8 renders on an HTML5 canvas and has to redraw with every change to your shape. If you are changing the shapes in an interval like this and the interval is too small, the renderer will wait for the changes to stop for a period of time before drawing. Looking at your code you aren't specifying an interval time which means it is firing this even a ridiculous number of times.
I am using openlayer 3.9.0 .I have the below code , in which i have to draw a number of overlay on map.
These overlay are coming but not at exact coordinate. But as soon as i click on map some where these overlay moves to correct position.
To overcome tis i tried to hit click event on hidden div also but it is not working. Only when i click on map somewhere then only these anamoly go tpo correct position.
for(var anamolyIndex=0; anamolyIndex< self.anamolyes.array.length ; anamolyIndex++)
{
tmpAnamolyObject = self.anamolyes.array[anamolyIndex];
elem = document.getElementById(tmpAnamolyObject.coordinates);
coordinate = tmpAnamolyObject.coordinates.split(",");
longitude = parseFloat(coordinate[0]);
lattitude = parseFloat(coordinate[1]);
position = ol.proj.transform([longitude, lattitude],'EPSG:4326', 'EPSG:3857');
popup = new ol.Overlay({
//position: position,
element: elem,
stopEvent:true,
positioning : 'center-center'
});
tmpAnamolyObject.type = "ANAMOLY";
popup['identity'] = tmpAnamolyObject;
elem.addEventListener('click', function() {
var coordinates = this.getAttribute('id');
self.send('onAnamolyClick',coordinates);
});
popup.setPosition(position);
self.map.addOverlay(popup);
}
I made a function to get the closer feature to the one clicked. I use Openlayers 3.9.0 and the getClosestFeatureToCoordinate method.
var select = new ol.interaction.Select();//simple click interaction
map.addInteraction(select);//add it to the map
select.on('select', function(e) {
//get the extent of the first selected feature
var aa = e.selected[0].getGeometry().getExtent();
//in case of line or polygon get the center of that extent
var oo = ol.extent.getCenter(aa);
//use it to get the name of the closest feature
console.log((sourceVector.getClosestFeatureToCoordinate(oo)).get("mylayer_name")) ;
});
But in a case like the following
if I click the "u" Polygon (bottom down) I get "u" instead of , say, "e"
if I click any point I get its name , instead of the closest feature's name. I click "testpoint9" and I get "testpoint9" instead of "u" or "e". I click "h" and I get "h" instead of "p" or "k".
So maybe has to do with points, so I changed the select.on event function to
select.on('select', function(e) {
var closestType = e.selected[0].getGeometry().getType();
var oo;
if (closestType === 'Point'){
oo = e.selected[0].getGeometry().getCoordinates();
}
else{
var aa = e.selected[0].getGeometry().getExtent();
oo = ol.extent.getCenter(aa);
}
console.log("---------------------------------------------------");
console.log("Name: "+sourceVector.getClosestFeatureToCoordinate(oo).get('mylayer_name'));
})
and still nothing. So, how I fix this?
Thanks
When You click inside the "u" polygon - the distance to it is 0.
When you click on something - that thing will always be the closest (to itself).
What you can do there, is removing the clicked element from the layer, run the algorithm (without clicked point) and put the point back on the layer.
If You are afraid that point could be invisible for too long (but it shouldn't), place it in another layer for the time of algorithm.
select.on('select', function(e) {
var clicked = e.selected[0];
sourceVector.removeFeature(clicked);
var closest = sourceVector.getClosestFeatureToCoordinate(e.coordinate);
sourceVector.addFeature(clicked);
var closestType = closest.getType();
if (closestType === 'Point'){
oo = e.selected[0].getGeometry().getCoordinates();
}
else{
var aa = e.selected[0].getGeometry().getExtent();
oo = ol.extent.getCenter(aa);
}
})
I have two styles of interactions, one highlights the feature, the second places a tooltop with the feature name. Commenting both out, they're very fast, leave either in, the map application slows in IE and Firefox (but not Chrome).
map.addInteraction(new ol.interaction.Select({
condition: ol.events.condition.pointerMove,
layers: [stationLayer],
style: null // this is actually a style function but even as null it slows
}));
$(map.getViewport()).on('mousemove', function(evt) {
if(!dragging) {
var pixel = map.getEventPixel(evt.originalEvent);
var feature = null;
// this block directly below is the offending function, comment it out and it works fine
map.forEachFeatureAtPixel(pixel, function(f, l) {
if(f.get("type") === "station") {
feature = f;
}
});
// commenting out just below (getting the feature but doing nothing with it, still slow
if(feature) {
target.css("cursor", "pointer");
$("#FeatureTooltip").html(feature.get("name"))
.css({
top: pixel[1]-10,
left: pixel[0]+15
}).show();
} else {
target.css("cursor", "");
$("#FeatureTooltip").hide();
}
}
});
I mean this seems like an issue with OpenLayers-3 but I just wanted to be sure I wasn't overlooking something else here.
Oh yeah, there's roughly 600+ points. Which is a lot, but not unreasonably so I would think. Zooming-in to limit the features in view definitely helps. So I guess this is a # of features issue.
This is a known bug and needs more investigation. You can track progress here: https://github.com/openlayers/ol3/issues/4232.
However, there is one thing you can do to make things faster: return a truthy value from map.forEachFeatureAtPixel to stop checking for features once one was found:
var feature = map.forEachFeatureAtPixel(pixel, function(f) {
if (f.get('type') == 'station') {
return feature;
}
});
i had same issue, solved a problem by setInterval, about this later
1) every mouse move to 1 pixel fires event, and you will have a quee of event till you stop moving, and the quee will run in calback function, and freezes
2) if you have an objects with difficult styles, all element shown in canvas will take time to calculate for if they hit the cursor
resolve:
1. use setInterval
2. check for pixels moved size from preview, if less than N, return
3. for layers where multiple styles, try to simplify them by dividing into multiple ones, and let only one layer by interactive for cursor move
function mouseMove(evt) {
clearTimeout(mm.sheduled);
function squareDist(coord1, coord2) {
var dx = coord1[0] - coord2[0];
var dy = coord1[1] - coord2[1];
return dx * dx + dy * dy;
}
if (mm.isActive === false) {
map.unByKey(mm.listener);
return;
}
//shedules FIFO, last pixel processed after 200msec last process
const elapsed = (performance.now() - mm.finishTime);
const pixel = evt.pixel;
const distance = squareDist(mm.lastP, pixel);
if (distance > 0) {
mm.lastP = pixel;
mm.finishTime = performance.now();
mm.sheduled = setTimeout(function () {
mouseMove(evt);
}, MIN_ELAPSE_MSEC);
return;
} else if (elapsed < MIN_ELAPSE_MSEC || mm.working === true) {
// console.log(`distance = ${distance} and elapsed = ${elapsed} mesc , it never should happen`);
mm.sheduled = setTimeout(function () {
mouseMove(evt);
}, MIN_ELAPSE_MSEC);
return;
}
//while multithreading is not working on browsers, this flag is unusable
mm.working = true;
let t = performance.now();
//region drag map
const vStyle = map.getViewport().style;
vStyle.cursor = 'default';
if (evt.dragging) {
vStyle.cursor = 'grabbing';
}//endregion
else {
//todo replace calback with cursor=wait,cursor=busy
UtGeo.doInCallback(function () {
checkPixel(pixel);
});
}
mm.finishTime = performance.now();
mm.working = false;
console.log('mm finished', performance.now() - t);
}
In addition to #ahocevar's answer, a possible optimization for you is to utilize the select interaction's select event.
It appears that both the select interaction and your mousemove listener are both checking for hits on the same layers, doing double work. The select interaction will trigger select events whenever the set of selected features changes. You could listen to it, and show the popup whenever some feature is selected and hide it when not.
This should reduce the work by half, assuming that forEachFeatureAtPixel is what's hogging the system.