Vector data(point) is drawn in wrong place on map (OpenLayers) - javascript

I need to show a map (world map, used default OpenLayers WMS) and one point on it (with events like onhover, etc). Here is my code:
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
maxResolution: 6000
};
map = new OpenLayers.Map('map', options);
var wmsLayer = new OpenLayers.Layer.WMS(
"OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0",
{layers: 'basic'}
);
var vectors = new OpenLayers.Layer.Vector("Vector Layer");
point = new OpenLayers.Geometry.Point(20.088844299316406, 51.8321709083475);
vectors.addFeatures([new OpenLayers.Feature.Vector(point)]);
map.addLayers([wmsLayer, vectors]);
map.zoomToMaxExtent();
But this code locates the point is drawn not in correct place, but somewhere near Africa (that place lat and lon is 0, 0). Question: Why this happens and can I fix it? I just need to locate the point to the correct place. Paradox when I print this point in console then it shows that the point lan and lon are as needed (as defined). But it is still in the wrong place...

Your map is in 900913, and point in 4326 projection. You have to transform it from 4326 to 900913:
point = new OpenLayers.Geometry.Point(20.088844299316406, 51.8321709083475);
point.transform(
new OpenLayers.Projection("EPSG:4326"),
new OpenLayers.Projection("EPSG:900913")
);
Also, consider centering your map by feature. zoomToMaxExtent() centers map to 0, 0. Since you have set maxResolution to 6000, only small part of map is visible and feature may be out of map bounds.
map.zoomToMaxExtent();
map.setCenter([point.x, point.y]);

Seems that new OpenLayers.Feature.Vector() uses OpenLayers.Geometry but not an OpenLayers.Geometry.Point type. But I never done such kind of app. Just a suggestion which looks reasonable.

Related

Retrieve first two digits from google v3 API response

I'm getting "sick" with in a simply problem. I'm using OpenLayers to display a map with a google map base layer. As an user suggestion i'm doing a request to the google geocode API with an address provided by the user.
The problem:
The google api response is like that:
lat: "-34.8836111"
lon: "-56.1819444"
After that i have to create a LonLat OpenLayers object and make a transformation, like that:
var lonLat = new OpenLayers.LonLat(position.coords.longitude,
position.coords.latitude)
.transform(
new OpenLayers.Projection("EPSG:4326"), //transform from WGS 1984
window.user_map.getProjectionObject() //to Spherical Mercator Projection
);
The problem is that lonLat format is in a different precission.
lat: -4148075.5841099103
lon: -6254145.441513423
I need to have only the first two integers digits that allow that displayable using the google map API (in another page).
Any help? This could be solved in ruby for example in a bebore_save method that formats the coordinates, or in the client side with javascript/jquery
Regards.
Convert numbers to a string:
var myStringLat = 123456.123654 + "";
Then get first two digits:
var myStringLat2Digits = myStringLat.substr(1, 2);
Then convert back to numbers:
var myNumberLat2Digits = Number(myStringlat2Digits, 10);
The problem was solved with a inverse order transformation before showing the second google map.
Like that:
var lonLat = new OpenLayers.LonLat(position.coords.longitude,
position.coords.latitude)
.transform(
window.user_map.getProjectionObject(), //transform from WGS 1984
new OpenLayers.Projection("EPSG:4326") //to Spherical Mercator Projection
);

openlayers create marker (feature with icon) from WKT

I have a point object WKT. Like this: POINT (25.04568 48.221548). Also I have an icon in my project folder.
My goal is to show on a map an icon that represents a feature. Can it be just a normal OpenLayers feature (if yes, then how can I define that it should represent and icon) or do I need to create an OpenLayers marker (somehow create LonLat from WKT)?
It is fairly easy to add an icon if you have the point.
Just view the javascript source of this page:
OpenLayers example markers page
OpenLayers examples page
An important part to remember is that if you use an icon you have to use .clone() on it if you need it to display more than once.
Code snippet from above example:
"...
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
var size = new OpenLayers.Size(21,25);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png',size,offset);
markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon));
var halfIcon = icon.clone();
markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,45),halfIcon));
marker = new OpenLayers.Marker(new OpenLayers.LonLat(90,10),icon.clone());
..."
Something like this on your point object:
point.transform(
new OpenLayers.Projection("EPSG:900913"), //from
map.getProjectionObject() //to
);
Of course you need to know what your points projection is.
There are plenty of examples out there.
Projections and OpenLayers.Geometry.Point in openlayers
Spherical Mercator - OpenLayers Library Documentation

Erratic overlay behavior with custom projection, Google Maps API v3

I want to browse a single image with the Google Maps API, for which I've defined my own projection. I wanted to use a GroundOverlay instead of several image tiles, because I only have one small-resolution image, but I wanted it to still be zoomable. However, I get some erratic behavior when trying to work with this projection:
No overlays show up at all at zoom level 0.
At zoom level 1 and higher, Markers show up, but GroundOverlays still don't.
However, I can get GroundOverlays to show up very briefly, if I zoom out from any level. It will only show while it's zooming out and disappear again immediately. Also, while it does show up shortly, it does not show up at the right coordinates, but the Markers do.
I'm rather new to the API, so I would not be surprised if it was a simple oversight on my part, but I just can't see what could cause this. Here is the code for my projection, which just maps the lat/lng linearly to map coordinates:
function EvenMapProjection() {
var xPerLng = 512/360;
var yPerLat = 512/180;
this.fromLatLngToPoint = function(latlng) {
var x = (latlng.lng()+180)*xPerLng;
var y = (latlng.lat()+90)*yPerLat;
console.log('Lng', latlng.lng(), 'Lat', latlng.lat(), '-> Point', x, y);
return new google.maps.Point(x, y);
};
this.fromPointToLatLng = function(point) {
var lat = point.y/yPerLat-90;
var lng = point.x/xPerLng-180;
console.log('Point', point.x, point.y, '-> Lng', lng, lat);
return new google.maps.LatLng(lat, lng);
};
}
An example of what I'm trying to do without the projection (using the default Mercator projection):
http://95.156.209.71/tmp/a.html
The same example with the projection as defined above:
http://95.156.209.71/tmp/b.html
And finally an example using the projection but without the GroundOverlay, and instead just using tiled images (always the same image):
http://95.156.209.71/tmp/c.html
The last link also shows the Marker at LatLng(0, 0) appear at zoom level 1 (or higher), but not at level 0.
Is there something I'm just missing, or some buggy code, or is this actually a problem in the API?
I just found out that my mistake was in the definition of the ground overlay. I was at zoom level 0, which meant that I set the bounds for the overlay from (-90,-180) to (90,180), but the API seems to have issues with these levels, because they wrap longitude, hence I got weird errors. I adjusted it to be at level 1 for minimum zoom, and set the overlay from (-45,-90) to (45,90), and now it all works fine.

OpenLayers, and GeoJSON, not multiply marker on same coordinates

My code is showing markers from GeoJSON, when I'm haved zoomed into zoom-level 10,it load the GeoJSON-file, but how do I avoid to reput out the same markers?
Is there a way to check if there already exist a marker on a specific place?
The code
map.events.register("zoomend", null, function(){
if(map.zoom == 10)
{
var bounds = map.getExtent();
console.log(bounds);
var ne = new OpenLayers.LonLat(bounds.right,bounds.top).transform(map.getProjectionObject(),wgs84);
var sw = new OpenLayers.LonLat(bounds.left,bounds.bottom).transform(map.getProjectionObject(),wgs84);
var vectorLayer = new OpenLayers.Layer.Vector();
map.addLayer(vectorLayer);
$.getJSON('ajax.php?a=markers&type=json&sw=('+sw.lon+','+sw.lat+')&ne=('+ne.lon+','+ne.lat+')',function(data){
//$.getJSON('test.json',function(data){
var geojson_format = new OpenLayers.Format.GeoJSON({
'externalProjection': wgs84,
'internalProjection': baseProjection
});
vectorLayer.addFeatures(geojson_format.read(data));
});
}
});
Why not use the BBOX Strategy [1] ?
That will do what you need, and will for sure be more performant (it will delete existing features and reload new ones on zoomend). Comparing features to add new will need a lot of comparison, and you can end with too much features on your map.
Check out the js source of the example.
HTH,
1 - http://openlayers.org/dev/examples/strategy-bbox.html
EDIT: if you want to change less code, a call to vectorLayer.removeAllFeatures() before adding will solve your problem… Do you really need to keep features out of bound?
First you would need to get the layer off the map using something like map.getLayersByName. Then you can iterate over layer.features to look for the feature you are adding.
If you can modify the backend to use BBOX, then the BBOX strategy with zoom level and projection settings would take care of a lot for you.

OpenLayers minimal zoom smaller than bounding box

I've got a problem with osm and openlayers.
first of all, my map object
var wgs84 = new OpenLayers.Projection("EPSG:4326");
var map = new OpenLayers.Map ('map',
{
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: wgs84,
maxExtent: new OpenLayers.Bounds(-180,-20, 180, 90),
controls: [
new OpenLayers.Control.MousePosition(),
new OpenLayers.Control.PanZoomBar(),
]
});
as you can see, my bounding box ends at -20, so the antarctis should be displayed.
but i'm able to zoom out so that i can see the whole world, and the map is smaller than the map-div (which is 900 * 500).
Is there any solution to fix it? you shouldn't be able to get a smaller map than the bounding box allows.
Have you implemented the restrictedExtent parameter?
(from the documentation)
restrictedExtent
{OpenLayers.Bounds} Limit map navigation to this extent where possible. If a non-null restrictedExtent is set, panning will be restricted to the given bounds. In addition, zooming to a resolution that displays more than the restricted extent will center the map on the restricted extent.
See an example here - This stops you panning beyond the bounds but does not restict the zoom levels. This seems to be a heavily reported missing feature that has not had many resolutions.
I believe this SO post has some workarounds for it thoughMin Max Zoom level in OpenLayers
Hope I have been some help.
Take a look at the sample I did at http://beta1234.com.sunflower.arvixe.com/maps/ (the server is a bit slow). It uses restrictedExtent and restricted zoom levels.

Categories