Hi Habr, today I will tell you a little about using osm for businesses and b2b.
Namely, how and why go from google maps api to osm, openlayers and happiness.
The first question that will certainly arise: why?
To begin with, the use of google maps api for non-public services is limited by the terms of service. Second: Google's Google Maps is exactly Google's Google Maps, and not to display everything that looks like a map. Those. if you wanted to display another substrate or add a raster layer rendered by a server in the local area network, prepare to sculpt the crutches. Well, just be prepared that if something is not in api, it will be painful to add. Third: you can not get the map data, respectively, you can not create a local map service for employees of the enterprise. That is, Google cards must be available from each client machine. It sounds crazy, but employees are not always open access to external networks.
Suppose I convinced you. Where to begin?
First, we connect the card to the openlayers. Everything is simple and not much different from google, yandex, leaflet.
')
Large companies can often afford to buy a map server and maps and distribute them on the local network via wms or tms. WMS and TMS are the standards by which you can get map image pieces. The main difference: for wms you can request an arbitrary piece of a map of arbitrary scale, for tms - a set of scales and dividing the map into small squares, which can be obtained fixedly.
Correspondingly, change the wms layer creation string to
for tms:
Also, no one bothers you to add all 3 layers to the map and switch between them, or add one of the layers on top of the other.
Projections
Now a few words about the rake, on which you are likely to step on.
Suppose you have added a single layer with a map layer with osm.org (OpenLayers.Layer.OSM), but you want the map to open otzummirovannoy to the Moscow region, and not to the whole world. We look at the latitude and longitude of Moscow and instead
map.zoomToMaxExtent
write
map.moveTo(
And we fall into the ocean. It's all about the coordinate system. For the map layer, the native coordinate system is EPSG: 900913. The reference point of the coordinates in it is the intersection of the Greenwich meridian and the equator, and the units of measure are meters. Accordingly, we hit 37 meters east and 55 meters north of the reference point.
The usual longitude and latitude imply that they are given in EPSG: 4326. Accordingly, it is necessary to recalculate the coordinates.
map.moveTo(
It is better to remember that there are a lot of coordinate systems in the world when specifying any coordinates in the openlayers. This adds a headache, but allows you to work with customer data if they use something exotic, for example, Pulkovo 42.
To do this, connect the proj4js (
trac.osgeo.org/proj4js/wiki/Download ) and add the line
Proj4js.defs['EPSG:28403'] = '+proj=tmerc +lat_0=0 +lon_0=39 +k=1 ' + '+x_0=500000 +y_0=0 +no_defs +a=6378140 +rf=298,257223563 +units=m ' + '+towgs84=28.000,-130.000,-95.000 +to_meter=1';
Now, when recalculating coordinates, you can specify a new projection.
This is not quite Pulkovo 42, but by slightly picking up the parameters, it is possible to achieve a normal display of data over layers in other coordinate systems.
Now that we’ve dealt with adding and displaying layers, we’ll move on to the markers, lines, and event handling.
Markers
There are 2 types in the drivers:
HTML (OpenLayers.Marker) and vector (OpenLayers.Geometry.Point). A little later, I will explain what is meant by a marker and why point.
HTML marker creates one or several divs, in which it places a picture and places it above the map in accordance with the coordinates. If you have ever watched a firebug or another debugger as a marker on a Google map, everything will be familiar to you. It is relatively easy for them to connect popups, it’s easy (since there is an html object) to work with from jQuerry, and yet the creators of the library do not recommend using them. Why? They are somewhat heavy: when you have 1 marker - everything is fine, when a thousand is bad. They are out of the general concept of storing and displaying data adopted in ol. Well, for practical reasons: when I started working with trainers, for such markers there was no drag control. However, it is not there now.
However, some code to add markers to the map:
Yes, there may be several layers with markers. Yes, you can control the visibility of layers and hide groups of markers as you like.
Now about who the vector markers are and about the “concept of storing and displaying data”.
Few people are now satisfied with the ability to simply display different raster layers with maps. The main charm in displaying your unique data on top of them. So, suppose we want to display on top of the map optical cables, copper cables and wells / supports through which this stuff passes. Each object will contain geometric information (how the cable itself passes / where the support or well is located) and attribute information (cable type, number of cable cores, signal attenuation, support height ... the list can be added to infinity). Actually this idea is directly implemented in Leers:
The object, “OpenLayers.Feature.Vector”, is stored along with its attributes, geometry, and, optionally, the display style.
For point features:
new OpenLayers.Feature.Vector(
A few words about styles.
In styles, you can specify how to display the geometry, using the attributes of the object. Depending on the type, you can use different icons, for example, draw wells with circles, and supports - with bars. You can define the fill color, thickness, and stroke color. Based on the attributes, text labels can be displayed for objects, etc. You can set a style for a specific object, for example, you can assign a style to a layer so that all the objects in the layer are displayed in accordance with it.
And yet to the markers:
* Dear grammar-nazi, it was an allusion to the children's song.
If you need to add several markers with the same style, it’s enough to use the same style object, but it is important to remember that changes in the style instance will affect all markers.
So, we added a marker. Now let's add the ability to move it, click on it, and respond to other events. Actually, event handling is the most different from other libraries that have been worked with (attentive reader who reads the whole article, without missing paragraphs, finds out that, first of all, it’s google and a bit of leaflet with Yandex).
Add a drag:
If the memory does not fail me, you will finally get to move the markers on the map.
Or add our popup marker on the click:
selectControl = new OpenLayers.Control.SelectFeature(markers, {
You can see an example here:
openlayers.org/dev/examples/select-feature-openpopup.htmlBig problems start when you need to:
- be able to move markers
- display hover (i.e. handle onmousein and onmouseout)
- handle click, double click on object
- handle click, dubclick outside object
This is a solvable problem, but the solution, perhaps, deserves a separate article.
Geocoding
Fuf, we added OSM to the site and learned how to display our data over. But still a significant part of Google's api (Yandex) is left out. Namely, geocoding (getting coordinates by address and addresses by coordinates) and routing.
About card routing in OSM I will tell you another time, now a few words about geocoding. I did not do reverse geocoding (address by coordinates), so I’ll stop looking at coordinates by address.
There are several options: use a ready-made search from nominatim or openstreetmap.ru, write your bike. A few words about why you might need your geocoder.
1. For example, you are only interested in Moscow, respectively, the data will be easier to import, and search queries will be simple, without specifying the city.
2. For some reason you can not give access to the external either from client machines or from the server.
3. You need a geocoder on your own client address database.
Well, there is no magic: the simplest option is to use Solr or Sphynx. In fact, I simply save the documents with the full address and coordinates of the object to solr.
To get a list of addresses, you can, for example, take the region of interest to you in shp format, load it into postgis, and then get addresses with a query like:
select bldng.osm_id, bldng."A_STRT", bldng."A_SBRB", bldng."A_HSNMBR", settle."NAME", ST_AsText(ST_Centroid(bldng.geom)) from building-polygon bldng join settlement-polygon settle on ST_Within(bldng.geom, settle.geom)
That's all for today. Next time I will try to tell you more about the event system in openlayers.
Links
Openlayers documentation -
dev.openlayers.org/docs/files/OpenLayers/Map-js.htmlThere's also a sandbox with examples -
openlayers.org/dev/examplesProj4js -
trac.osgeo.org/proj4jsA site with a description of different coordinate systems in different formats,
including in the proj4 format -
spatialreference.org