openlayers create marker (feature with icon) from WKT - javascript

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

Related

How to show the target location at a particular position of the map container

I created a simple map like in this example from the Leaflet.js tutorial:
var map=L.map('map').setView([51.505,-0.09], 13);
Now, the target location is shown centered in the map.
My map container has a size of 600x400 pixels. How can I achieve to show the given target at a custom position within the container? Let's say I want the location to appear horizontally centered but 50 pixels from top.
That's easy to do using two utility methods of L.Map called latLngToContainerPoint and it's counterpart containerPointToLatLng.
// Get LatLng position of the marker
var oldLatLng = marker.getLatLng();
// Convert LatLng to containerpoint in pixels.
var oldPoint = map.latLngToContainerPoint(oldLatLng);
// Calculate new point
var newPoint = L.point(oldPoint.x, oldPoint.y + (oldPoint.y - 50));
// Convert point to LatLng
var newLatLng = map.containerPointToLatLng(newPoint);
// Set new map view
map.setView(newLatLng);
Here's a working example on Plunker: http://plnkr.co/edit/8y5Klz?p=preview

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

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

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.

Zoom Setting On Google Marker

I wonder whether someone may be able to help me please.
I'm using this page to allow users to view markers saved in a MySQL database and to geocode/reverse geocode new marker positions.
I'm able to correctly center the map on the marker which is being loaded from the database, but the problem I'm having is that the map zooms in to it's maximum setting, whereas I would like to be able to set this manually.
I've tried adding another zoom control into my script here:
// add marker
var bounds = new google.maps.LatLngBounds();
var loc = new google.maps.LatLng(las[i],lgs[i]);
var marker = new google.maps.Marker({
position: loc,
map: window.map,
zoom: 8,
title: nms[i]
});
bounds.extend(loc);
map.fitBounds(bounds);
Unfortunately this has no affect. I appreciate that to some this may be a very minor fix, but I've been looking at this for sometime and I just can't seem to find a solution.
I just wondered whether someone may be able to look at this please and let me know where I've gone wrong?
POST UPDATE
I have worked out a solution using exisitng code and that suggested by #Andrew Leach. The working solution is:
// add marker
var bounds = new google.maps.LatLngBounds();
var loc = new google.maps.LatLng(las[i],lgs[i]);
var marker = new google.maps.Marker({
position: loc,
map: window.map,
title: nms[i]
});
bounds.extend(loc);
map.fitBounds(bounds);
map.setZoom(16);
Remove the references to the bounds.
You add a marker to the map, and create a LatLngBounds object which contains only that single point. You then ask the map to zoom in to fit the bounds into the map's viewport. Fitting a single location into the viewport will always zoom in as far as it can, and even then a single point can never fill the entire viewport.
However, adding zoom to the marker options won't work either, because zoom is not a valid option. Documentation
Instead, set the map's zoom explicitly, either with map.setZoom(8) or by including the zoom option in the map's options when you set it up.

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.

Categories