UNPKG

13.3 kBMarkdownView Raw
1---
2title: Frequently Asked Questions (FAQ)
3layout: doc.hbs
4---
5
6# Frequently Asked Questions (FAQ)
7
8Certain questions arise more often than others when users ask for help. This
9document tries to list some of the common questions that frequently get asked,
10e.g. on [Stack Overflow](http://stackoverflow.com/questions/tagged/openlayers).
11
12If you think a question (and naturally its answer) should be added here, feel
13free to ping us or to send a pull request enhancing this document.
14
15Table of contents:
16
17* [What projection is OpenLayers using?](#what-projection-is-openlayers-using-)
18* [How do I change the projection of my map?](#how-do-i-change-the-projection-of-my-map-)
19* [Why is my map centered on the gulf of guinea (or africa, the ocean, null-island)?](#why-is-my-map-centered-on-the-gulf-of-guinea-or-africa-the-ocean-null-island-)
20* [Why is the order of a coordinate [lon,lat], and not [lat,lon]?](#why-is-the-order-of-a-coordinate-lon-lat-and-not-lat-lon-)
21* [Why aren't there any features in my source?](#why-aren-t-there-any-features-in-my-source-)
22* [How do I force a re-render of the map?](#how-do-i-force-a-re-render-of-the-map-)
23* [Why are my features not found?](#why-are-my-features-not-found-)
24* [How do I create a custom build of OpenLayers?](#how-do-i-create-a-custom-build-of-openlayers-)
25* [Do I need to write my own code using Closure library?](#do-i-need-to-write-my-own-code-using-closure-library-)
26* [Do I need to compress my code with Closure compiler?](#do-i-need-to-compress-my-code-with-closure-compiler-)
27
28
29## What projection is OpenLayers using?
30
31Every map that you'll create with OpenLayers will have a view, and every view
32will have a projection. As the earth is three-dimensional and round but the 2D
33view of a map isn't, we need a mathematical expression to represent it. Enter
34projections.
35
36There isn't only one projection, but there are many common ones. Each projection
37has different properties, in that it accurately represents distances, angles or
38areas. Certain projections are better suited for different regions in the world.
39
40Back to the original question: OpenLayers is capable of dealing with most
41projections. If you do not explicitly set one, your map is going to use our
42default which is the Web Mercator projection (EPSG:3857). The same projection is
43used e.g. for the maps of the OpenStreetMap-project and commercial products such
44as Bing Maps or Google Maps.
45
46This projection is a good choice if you want a map which shows the whole world,
47and you may need to have this projection if you want to e.g. use the
48OpenStreetMap or Bing tiles.
49
50
51## How do I change the projection of my map?
52
53There is a good chance that you want to change the default projection of
54OpenLayers to something more appropriate for your region or your specific data.
55
56The projection of your map can be set through the `view`-property. Here are some
57examples:
58
59```javascript
60// OpenLayers comes with support for the World Geodetic System 1984, EPSG:4326:
61var map = new ol.Map({
62 view: new ol.View({
63 projection: 'EPSG:4326'
64 // other view properties like map center etc.
65 })
66 // other properties for your map like layers etc.
67});
68```
69
70```javascript
71// To use other projections, you have to register the projection in OpenLayers:
72//
73// By default OpenLayers does not know about the EPSG:21781 (Swiss) projection.
74// So we create a projection instance for EPSG:21781 and pass it to
75// ol.proj.addProjection to make it available to the library for lookup by its
76// code.
77var swissProjection = new ol.proj.Projection({
78 code: 'EPSG:21781',
79 // The extent is used to determine zoom level 0. Recommended values for a
80 // projection's validity extent can be found at https://epsg.io/.
81 extent: [485869.5728, 76443.1884, 837076.5648, 299941.7864],
82 units: 'm'
83});
84ol.proj.addProjection(swissProjection);
85
86// we can now use the projection:
87var map = new ol.Map({
88 view: new ol.View({
89 projection: swissProjection
90 // other view properties like map center etc.
91 })
92 // other properties for your map like layers etc.
93});
94```
95
96We recommend to lookup parameters of your projection (like the validity extent)
97over at [epsg.io](https://epsg.io/).
98
99
100## Why is my map centered on the gulf of guinea (or africa, the ocean, null-island)?
101
102If you have set a center in your map view, but don't see a real change in visual
103output, chances are that you have provided the coordinates of the map center in
104the wrong (a non-matching) projection.
105
106As the default projection in OpenLayers is Web Mercator (see above), the
107coordinates for the center have to be provided in that projection. Chances are
108that your map looks like this:
109
110```javascript
111var washingtonLonLat = [-77.036667, 38.895];
112var map = new ol.Map({
113 layers: [
114 new ol.layer.Tile({
115 source: new ol.source.OSM()
116 })
117 ],
118 target: 'map',
119 view: new ol.View({
120 center: washingtonLonLat,
121 zoom: 12
122 })
123});
124```
125
126Here `[-77.036667, 38.895]` is provided as the center of the view. But as Web
127Mercator is a metric projection, you are currently telling OpenLayers that the
128center shall be some meters (~77m and ~39m respectively) away from `[0, 0]`. In
129the Web Mercator projection the coordinate is right in the gulf of guinea.
130
131The solution is easy: Provide the coordinates projected into Web Mercator.
132OpenLayers has some helpful utility methods to assist you:
133
134```javascript
135var washingtonLonLat = [-77.036667, 38.895];
136var washingtonWebMercator = ol.proj.fromLonLat(washingtonLonLat);
137
138var map = new ol.Map({
139 layers: [
140 new ol.layer.Tile({
141 source: new ol.source.OSM()
142 })
143 ],
144 target: 'map',
145 view: new ol.View({
146 center: washingtonWebMercator,
147 zoom: 8
148 })
149});
150```
151
152The method `ol.proj.fromLonLat()` is available from version 3.5 onwards.
153
154If you told OpenLayers about a custom projection (see above), you can use the
155following method to transform a coordinate from WGS84 to your projection:
156
157```javascript
158// assuming that OpenLayers knows about EPSG:21781, see above
159var swissCoord = ol.proj.transform([8.23, 46.86], 'EPSG:4326', 'EPSG:21781');
160```
161
162
163## Why is the order of a coordinate [lon,lat], and not [lat,lon]?
164
165Because of two different and incompatible conventions. Latitude and longitude
166are normally given in that order. Maps are 2D representations/projections
167of the earth's surface, with coordinates expressed in the `x,y` grid of the
168[Cartesian system](https://en.wikipedia.org/wiki/Cartesian_coordinate_system).
169As they are by convention drawn with west on the left and north at the top,
170this means that `x` represents longitude, and `y` latitude. As stated above,
171OpenLayers is designed to handle all projections, but the default view is in
172projected Cartesian coordinates. It would make no sense to have duplicate
173functions to handle coordinates in both the Cartesian `x,y` and `lat,lon`
174systems, so the degrees of latitude and longitude should be entered as though
175they were Cartesian, in other words, they are `lon,lat`.
176
177If you have difficulty remembering which way round it is, use the language code
178for English, `en`, as a mnemonic: East before North.
179
180#### A practical example
181So you want to center your map on a certain place on the earth and obviously you
182need to have its coordinates for this. Let's assume you want your map centered
183on Schladming, a beautiful place in Austria. Head over to the wikipedia
184page for [Schladming](http://en.wikipedia.org/wiki/Schladming). In the top-right
185corner there is a link to [GeoHack](http://tools.wmflabs.org/geohack/geohack.php?pagename=Schladming&params=47_23_39_N_13_41_21_E_type:city(4565)_region:AT-6),
186which effectively tells you the coordinates are:
187
188 WGS84:
189 47° 23′ 39″ N, 13° 41′ 21″ E
190 47.394167, 13.689167
191
192So the next step would be to put the decimal coordinates into an array and use
193it as center:
194
195```javascript
196var schladming = [47.394167, 13.689167]; // caution partner, read on...
197// since we are using OSM, we have to transform the coordinates...
198var schladmingWebMercator = ol.proj.fromLonLat(schladming);
199
200var map = new ol.Map({
201 layers: [
202 new ol.layer.Tile({
203 source: new ol.source.OSM()
204 })
205 ],
206 target: 'map',
207 view: new ol.View({
208 center: schladmingWebMercator,
209 zoom: 9
210 })
211});
212```
213
214Running the above example will possibly surprise you, since we are not centered
215on Schladming, Austria, but instead on Abyan, a region in Yemen (possibly also a
216nice place). So what happened?
217
218Many people mix up the order of longitude and latitude in a coordinate array.
219Don't worry if you get it wrong at first, many OpenLayers developers have to
220think twice about whether to put the longitude or the latitude first when they
221e.g. try to change the map center.
222
223Ok, then let's flip the coordinates:
224
225```javascript
226var schladming = [13.689167, 47.394167]; // longitude first, then latitude
227// since we are using OSM, we have to transform the coordinates...
228var schladmingWebMercator = ol.proj.fromLonLat(schladming);
229
230var map = new ol.Map({
231 layers: [
232 new ol.layer.Tile({
233 source: new ol.source.OSM()
234 })
235 ],
236 target: 'map',
237 view: new ol.View({
238 center: schladmingWebMercator,
239 zoom: 9
240 })
241});
242```
243
244Schladming is now correctly displayed in the center of the map.
245
246So when you deal with EPSG:4326 coordinates in OpenLayers, put the longitude
247first, and then the latitude. This behaviour is the same as we had in OpenLayers
2482, and it actually makes sense because of the natural axis order in WGS84.
249
250If you cannot remember the correct order, just have a look at the method name
251we used: `ol.proj.fromLonLat`; even there we hint that we expect longitude
252first, and then latitude.
253
254
255## Why aren't there any features in my source?
256
257Suppose you want to load a KML file and display the contained features on the
258map. Code like the following could be used:
259
260```javascript
261var vector = new ol.layer.Vector({
262 source: new ol.source.KML({
263 projection: 'EPSG:3857',
264 url: 'data/kml/2012-02-10.kml'
265 })
266});
267```
268
269You may ask yourself how many features are in that KML, and try something like
270the following:
271
272```javascript
273var vector = new ol.layer.Vector({
274 source: new ol.source.KML({
275 projection: 'EPSG:3857',
276 url: 'data/kml/2012-02-10.kml'
277 })
278});
279var numFeatures = vector.getSource().getFeatures().length;
280console.log("Count right after construction: " + numFeatures);
281```
282
283This will log a count of `0` features to be in the source. This is because the
284loading of the KML-file will happen in an asynchronous manner. To get the count
285as soon as possible (right after the file has been fetched and the source has
286been populated with features), you should use an event listener function on the
287`source`:
288
289```javascript
290vector.getSource().on('change', function(evt){
291 var source = evt.target;
292 if (source.getState() === 'ready') {
293 var numFeatures = source.getFeatures().length;
294 console.log("Count after change: " + numFeatures);
295 }
296});
297```
298
299This will correctly report the number of features, `1119` in that particular
300case.
301
302
303## How do I force a re-render of the map?
304
305Usually the map is automatically re-rendered, once a source changes (for example
306when a remote source has loaded).
307
308If you actually want to manually trigger a rendering, you could use
309
310```javascript
311map.render();
312```
313
314...or its companion method
315
316```javascript
317map.renderSync();
318```
319
320## Why are my features not found?
321
322You are using `ol.Map#forEachFeatureAtPixel` or `ol.Map#hasFeatureAtPixel`, but
323it sometimes does not work for large icons or labels? The *hit detection* only
324checks features that are within a certain distance of the given position. For large
325icons, the actual geometry of a feature might be too far away and is not considered.
326
327In this case, set the `renderBuffer` property of `ol.layer.Vector` (the default
328value is 100px):
329
330```javascript
331var vectorLayer = new ol.layer.Vector({
332 ...
333 renderBuffer: 200
334});
335```
336
337The recommended value is the size of the largest symbol, line width or label.
338
339## How do I create a custom build of OpenLayers?
340
341Please refer to the [official create custom builds tutorial](tutorials/custom-builds.html)
342which explains how to create a custom build of OpenLayers with just those parts
343included that you want.
344
345
346## Do I need to write my own code using Closure library?
347
348OpenLayers is built on top of the [Google Closure JavaScript
349library](https://developers.google.com/closure/library/), but this
350does not mean that you must use that library in your application code.
351
352OpenLayers should play well with all sorts of JavaScript libraries out there,
353and you are in no way forced to use a specific one. Choose one that looks
354right for you.
355
356
357## Do I need to compress my code with Closure compiler?
358
359No, you don't need to do compress your code with the [Google Closure
360compiler](https://developers.google.com/closure/compiler/).
361
362It may be a good choice though, because when your application code and the
363OpenLayers source code is compiled together using closure compiler, the
364resulting build will most probably be the smallest in terms of byte-size. For
365more details refer to the
366[compile application and OpenLayers together tutorial](tutorials/closure.html).
367
368If you don't want to use the closure compiler, or you can't, you are not at all
369forced to use it.
370
371