ol.overlay is not setting the position correctly - openlayers-3

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);
}

Related

Highcharts Highmaps zoom to latitude longitude

I built a world map with a drop down menu that changes the zoom level: see fiddle
This is my function:
$('#func').change(function () {
var chart = $('#map').highcharts();
var v = $(this).val();
if(v == "1") {
$('#map').highcharts().mapZoom(10);
$('#map').highcharts().mapZoom(.4);
chart.redraw();
}
});
In addition I want to change the position of the map. How can I change latitude and longitude after a value is selected?
Using the mapZoom method you can change the current map view. You only have to add the second and third argument to that method. This is the X and Y position of the new zoom centre.
For calculating that value from latitude/longitude you might use the fromLatLonToPoint method.
In the demo below I implemented it for Europe.
API:
https://api.highcharts.com/class-reference/Highcharts.Chart#mapZoom
https://api.highcharts.com/class-reference/Highcharts.Chart.html#fromLatLonToPoint
Live demo:
https://jsfiddle.net/BlackLabel/xs8nLgho/

Adding "SCNNode" to ScreenView to current view of the camera

I've got an image that im trying to add to the current camera location of the Screenview ARSCNView session. Whatever I do it seems to put the image behind the current location of the phone camera and i have to move it back to see it. I have the following code:
var currentFrame = SceneView.Session.CurrentFrame;
if (currentFrame == null) return;
var threeVector = new SCNVector3(currentFrame.Camera.Transform.Column3.X + 0.005f,
currentFrame.Camera.Transform.Column3.Y - 0.02f,
currentFrame.Camera.Transform.Column3.Z - 0.05f);
var scaleFactor = imgToAdd.Size.Width / 0.05;
float width = float.Parse((imgToAdd.Size.Width / scaleFactor).ToString());
float height = float.Parse((imgToAdd.Size.Height / scaleFactor).ToString());
var box = new SCNPlane {
Width = width,
Height = height
};
var cubeNode = new SCNNode {
Position = threeVector,
Geometry = box
};
var mat = new SCNMaterial();
mat.Diffuse.Contents = imgToAdd;
mat.LocksAmbientWithDiffuse = true;
cubeNode.Geometry.Materials = new[] { mat };
SceneView.Scene.RootNode.AddChildNode(cubeNode);
Just trying to execute a simple idea of the ARKit paint apps that you see all over the app store now. So the imgToAdd is a snapshot of the scribble that the user has already put onto the screen and this event is fired at the touchended after an image is created from the view scribbled on.
Any ideas on what I need to change to get it to line up with the current view of the camera on the phone?

getClosestFeatureToCoordinate does not work for Points

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);
}
})

Stupid mouse move coordinates in dart

I am learning Dart and I was trying to make a very simple drageable HTML element. I followed patterns I'm used to from javascript but it doesn't work as expected.
When making drageable object from scratch you usually do the following:
Listen on mouse down event on that object
Upon mouse down, remember mouse coordinates relative to the object's top-left corner
Listen for any mouse movement. For every move operation, move the object to cursor location minus the coordinates you remembered earlier.
Upon any mouse up event, stop following mouse movement.
So I produced this code:
class DrageableControl {
DivElement _elm;
DrageableControl(String txt, int x, int y) {
//Create element and set up styles
var elm = this.setupElement(x, y);
//Append element to document, add some text and start listeners
document.body.append(elm);
elm.text = txt;
setupEvents();
}
//This function creates all event necessary for drag operations
setupEvents() {
Point relativeMouseOffset = null;
_elm.onMouseDown.listen((MouseEvent e) {
Rectangle myPos = _elm.getBoundingClientRect();
relativeMouseOffset = new Point(e.offset.x-myPos.left, e.offset.y-myPos.top);
e.preventDefault();
return false;
});
//Of course this is completely wrong, the listener should only be added for the duration of dragging
document.onMouseMove.listen((MouseEvent e) {
if(relativeMouseOffset!=null) {
print("Clicked at: ${relativeMouseOffset}\nCurrent mouse position:${e.offset}");
_elm.style.top = "${(e.offset.y/*-relativeMouseOffset.y*/)}px";
_elm.style.left = "${(e.offset.x/*-relativeMouseOffset.x*/)}px";
}
});
document.onMouseUp.listen((MouseEvent e){
relativeMouseOffset = null;
});
}
setupElement(int x, int y) {
var elm = this._elm = new DivElement();
//TODO: Use css?
elm.style.position = "absolute";
elm.style.top = "${y}px";
elm.style.left = "${x}px";
elm.style.border = "1px solid red";
elm.style.backgroundColor = "#FFAAAA";
elm.style.cursor = "default";
//elm.style.transition = "top 1s";
return elm;
}
}
Problem is, that some coordinates delivered by MouseMove are complete nonsense. See the console:
Clicked at: Point(-76.0, -143.0)
Current mouse position:Point(1, 1)
Clicked at: Point(-76.0, -143.0)
Current mouse position:Point(374, 272)
Clicked at: Point(-76.0, -143.0)
Current mouse position:Point(1, 0)
Clicked at: Point(-76.0, -143.0)
Current mouse position:Point(376, 273)
Clicked at: Point(-76.0, -143.0)
Current mouse position:Point(0, 1)
As you can see every second mouse move event delivers broken data - coordinates right around [0, 0]. So how can I filter out this invalid data? Why does it happen?
So far I'm probably fixing this by adding:
if(e.offset.x+e.offset.y<5)
return;
Use e.client.x/e.client.y instead.

How to set Monotouch map between two points

How can I center a map between two points? Sort of like when the native map application generates directions between location A and location B. I'm got a start coordinate and an end coordinate and I'll like to show two pins. I can place the pins in place, but I'm not sure how to set the center of the map.
Do I need to find the math to work out the exact distance from the points and set the map to that location? Is there a built in function for this?
this.currentMapView.SetCenterCoordinate (annotation.Coordinate, true);
Calculating the midpoint between two coordinates needs a simple formula. For example, let's say you have two coordinates: (x1,y1) and (x2,y2).
Their midpoint coordinate is: ( (x1+x2)/2, (y1+y2)/2 ).
So for example, in map coordinates, let's say you have the following start/end points:
a. long: 40, lat: 39
b. long: 41, lat: 38
Their midpoint coordinate is: ( (40+41)/2, (39+38)/2 ) = (40.5, 38.5)
So you set the map view's center coordinate to the outcome of this formula.
I am not aware of a built-in function for calculating this.
Taken from: http://codisllc.com/blog/zoom-mkmapview-to-fit-annotations/
BasicMapAnnotation is inherit class from MKAnnotation
private void GetRegion(MKMapView mapView)
{
var userWasVisible = mapView.ShowsUserLocation;
mapView.ShowsUserLocation = false; // ignoring the blue blip
// start with the widest possible viewport
var tl = new CLLocationCoordinate2D(-90, 180); // top left
var br = new CLLocationCoordinate2D(90, -180); // bottom right
foreach (var an in mapView.Annotations)
{
// narrow the viewport bit-by-bit
CLLocationCoordinate2D coordinate = ((BasicMapAnnotation) an).Coordinate;
tl.Longitude = Math.Min(tl.Longitude, coordinate.Longitude);
tl.Latitude = Math.Max(tl.Latitude, coordinate.Latitude);
br.Longitude = Math.Max(br.Longitude, coordinate.Longitude);
br.Latitude = Math.Min(br.Latitude, coordinate.Latitude);
}
var center = new CLLocationCoordinate2D
{
// divide the range by two to get the center
Latitude = tl.Latitude - (tl.Latitude - br.Latitude)*0.5
,
Longitude = tl.Longitude + (br.Longitude - tl.Longitude)*0.5
};
var span = new MKCoordinateSpan
{
// calculate the span, with 20% margin so pins aren’t on the edge
LatitudeDelta = Math.Abs(tl.Latitude - br.Latitude)*1.2
,
LongitudeDelta = Math.Abs(br.Longitude - tl.Longitude)*1.2
};
var region = new MKCoordinateRegion {Center = center, Span = span};
region = mapView.RegionThatFits(region); // adjusts zoom level too
mapView.SetRegion(region, true); // animated transition
mapView.ShowsUserLocation =
userWasVisible;
}
} ``

Resources