Skip to content

Commit 4cd2d28

Browse files
committed
Better tiles render and webmercator projection
Projections: - Add WebMercator projection and setup by default (in fact previous used Mercator projection was similar to WebMercator projection) - Add classic Mercator projection - Small UTM projection cleaning - Create benchs in a new class - refactoring of projection side, more clear methods names - remove not used methods MapTilesLayer : - Enhanced current tile z level processing : only one time at each scale changes. - Better tiles rendering (with limited magic numbers and computed gap) - Can be used with others projections (i.e. UTM) but with cool glitches :) Add tests Bench : Time for project and reverse project 1 milions of positions : - Web Mercator : 274ms - Mercator : 1441ms - UTM : 2346ms
1 parent 59342ea commit 4cd2d28

15 files changed

Lines changed: 779 additions & 124 deletions
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"
2+
I am a bench class to test performances
3+
"
4+
Class {
5+
#name : #GeoViewBench,
6+
#superclass : #Object,
7+
#category : #'GeoView-Examples'
8+
}
9+
10+
{ #category : #projections }
11+
GeoViewBench class >> timeToProjectCoordinates [
12+
"Transform coordinates is several projections and return the result is an array"
13+
14+
<script>
15+
| absoluteCoordinatesList projections results |
16+
absoluteCoordinatesList := (1 to: 1000000) collect: [ :i |
17+
AbsoluteCoordinates random ].
18+
projections := {
19+
GeoViewMercatorProjection new.
20+
GeoViewWebMercatorProjection new.
21+
GeoViewUTMProjection new }.
22+
results := Dictionary new.
23+
24+
"project"
25+
projections do: [ :proj |
26+
| time cartesianCoordinatesList |
27+
cartesianCoordinatesList := OrderedCollection new.
28+
"first => projection from lat lon to cart"
29+
time := [
30+
cartesianCoordinatesList :=
31+
(absoluteCoordinatesList collect: [ :coord |
32+
proj projLatLonToCart: coord ]) ] timeToRunWithoutGC.
33+
"second => projection from cart to lat lon"
34+
time := time + [
35+
cartesianCoordinatesList do: [ :coord |
36+
coord ifNotNil:[ proj projCartToLatLon: coord ] ] ] timeToRunWithoutGC.
37+
results at: proj printString put: time ].
38+
39+
"show result"
40+
results inspect
41+
]
42+
43+
{ #category : #'see class side' }
44+
GeoViewBench >> seeClassSide [
45+
]

src/GeoView-Examples/GeoViewExamples.class.st

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,21 @@ GeoViewExamples class >> exampleGeoViewWithCartoTilesLayerUsingOSM [
751751
^ self openViewInWindow: element
752752
]
753753

754+
{ #category : #'examples - tiles provider' }
755+
GeoViewExamples class >> exampleGeoViewWithCartoTilesLayerUsingOSMWithMercatorProjection [
756+
"This example show a map layer (assuming an internet connection to default url open street map"
757+
758+
| element layer |
759+
element := GeoViewElement new.
760+
element maxScale: element maxScale * 8.
761+
762+
"add carto layer"
763+
layer := GeoViewMapTilesLayer new name: 'Tiles Layer'.
764+
element addLayer: layer.
765+
766+
^ self openViewInWindow: element
767+
]
768+
754769
{ #category : #'examples - tiles provider' }
755770
GeoViewExamples class >> exampleGeoViewWithCartoTilesLayerUsingOSMWithSmallTileSize [
756771
"This example show a map layer (assuming an internet connection to default url open street map"
@@ -1110,7 +1125,7 @@ GeoViewExamples class >> exampleTissotIndicatorMercator [
11101125

11111126
| element objects |
11121127
element := GeoViewUtils createGeoViewForGeoObjects.
1113-
"element mapProjection: GeoViewMercatorProjection new." "by default"
1128+
element mapProjection: GeoViewMercatorProjection new.
11141129
"laborde: better to have a vectorial map to considere the deformation because tiles are not available for all projections"
11151130

11161131
"create sample datas"
@@ -1146,6 +1161,23 @@ GeoViewExamples class >> exampleTissotIndicatorUTM [
11461161

11471162
]
11481163

1164+
{ #category : #'examples - projections' }
1165+
GeoViewExamples class >> exampleTissotIndicatorWebMercator [
1166+
"This example implement the indicator of Tissot (Nicolas August) for a projection, this indicator indicate the level of deformation of the selection projection"
1167+
1168+
| element objects |
1169+
element := GeoViewUtils createGeoViewForGeoObjects.
1170+
"element mapProjection: GeoViewWebMercatorProjection new." "by default"
1171+
"laborde: better to have a vectorial map to considere the deformation because tiles are not available for all projections"
1172+
1173+
"create sample datas"
1174+
objects := self createTissotIndicatorCircles.
1175+
element addObjects: objects.
1176+
1177+
^ self openViewInWindow: element
1178+
1179+
]
1180+
11491181
{ #category : #'examples - dshapeslayer' }
11501182
GeoViewExamples class >> exampleVisibilityDShapesLayer [
11511183

src/GeoView-Tests/GeoViewAbstractElementTest.class.st

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ GeoViewAbstractElementTest >> testInitialize [
175175
self assert: geoView extent equals: 1000 @ 1000.
176176
self
177177
assert: geoView mapProjection class
178-
equals: GeoViewMercatorProjection.
178+
equals: GeoViewWebMercatorProjection.
179179
self
180180
assert: geoView displayToGraphicProjection class
181181
equals: GeoView2DProjection.

src/GeoView-Tests/GeoViewMercatorProjectionTest.class.st

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,69 @@ GeoViewMercatorProjectionTest >> testEpsgCode [
1919
self assert: projection epsgCode equals: 3395
2020
]
2121

22+
{ #category : #tests }
23+
GeoViewMercatorProjectionTest >> testGeodesicCrossesValidDomainFromTo [
24+
25+
self deny: (projection
26+
geodesicCrossesValidDomainFrom: AbsoluteCoordinates zero
27+
to:
28+
(AbsoluteCoordinates latitudeInDegrees: 45 longitudeInDegrees: 100)).
29+
30+
self deny: (projection
31+
geodesicCrossesValidDomainFrom: AbsoluteCoordinates zero
32+
to:
33+
(AbsoluteCoordinates latitudeInDegrees: 0 longitudeInDegrees: 0)).
34+
35+
self deny: (projection
36+
geodesicCrossesValidDomainFrom: AbsoluteCoordinates zero
37+
to:
38+
(AbsoluteCoordinates latitudeInDegrees: 84 longitudeInDegrees: 180)).
39+
40+
self deny: (projection
41+
geodesicCrossesValidDomainFrom: AbsoluteCoordinates zero
42+
to:
43+
(AbsoluteCoordinates latitudeInDegrees: -80 longitudeInDegrees: 180)).
44+
45+
self deny: (projection
46+
geodesicCrossesValidDomainFrom: (AbsoluteCoordinates latitudeInDegrees: 5.08 longitudeInDegrees: -19.01)
47+
to:
48+
(AbsoluteCoordinates latitudeInDegrees: 5.08 longitudeInDegrees: -19.00)).
49+
50+
"projection limits"
51+
self assert: (projection
52+
geodesicCrossesValidDomainFrom: AbsoluteCoordinates zero
53+
to:
54+
(AbsoluteCoordinates latitudeInDegrees: 90 longitudeInDegrees: 100)).
55+
56+
self assert: (projection
57+
geodesicCrossesValidDomainFrom: AbsoluteCoordinates zero
58+
to:
59+
(AbsoluteCoordinates latitudeInDegrees: -90 longitudeInDegrees: 100)).
60+
]
61+
62+
{ #category : #tests }
63+
GeoViewMercatorProjectionTest >> testIsAbsoluteCoordinatesOutsideProjectionLimit [
64+
65+
self deny: (projection isAbsoluteCoordinatesOutsideProjectionLimit:
66+
AbsoluteCoordinates zero).
67+
68+
self deny: (projection isAbsoluteCoordinatesOutsideProjectionLimit:
69+
AbsoluteCoordinates frBrest).
70+
71+
"out"
72+
self assert:
73+
(projection isAbsoluteCoordinatesOutsideProjectionLimit:
74+
AbsoluteCoordinates new).
75+
76+
self assert:
77+
(projection isAbsoluteCoordinatesOutsideProjectionLimit:
78+
(AbsoluteCoordinates latitudeInDegrees: -90 longitudeInDegrees: 0)).
79+
80+
self assert:
81+
(projection isAbsoluteCoordinatesOutsideProjectionLimit:
82+
(AbsoluteCoordinates latitudeInDegrees: 90 longitudeInDegrees: 0))
83+
]
84+
2285
{ #category : #tests }
2386
GeoViewMercatorProjectionTest >> testKey [
2487

@@ -31,6 +94,44 @@ GeoViewMercatorProjectionTest >> testName [
3194
self assert: projection name equals: 'Mercator'
3295
]
3396

97+
{ #category : #tests }
98+
GeoViewMercatorProjectionTest >> testProjCartToLatLon [
99+
100+
"Brest"
101+
| cartesian absolute reference |
102+
reference := AbsoluteCoordinates frBrest.
103+
cartesian := CartesianCoordinates xInMeters: -499082 yInMeters: 6203898.
104+
absolute := projection projCartToLatLon: cartesian.
105+
self assert: (absolute latitudeInDegrees closeTo: (reference latitudeInDegrees) precision: 0.0001).
106+
self assert: (absolute longitudeInDegrees closeTo: (reference longitudeInDegrees) precision: 0.0001).
107+
108+
"Paris"
109+
reference := AbsoluteCoordinates frParis.
110+
cartesian := CartesianCoordinates xInMeters: 259745 yInMeters: 6284473.
111+
absolute := projection projCartToLatLon: cartesian.
112+
self assert: (absolute latitudeInDegrees closeTo: (reference latitudeInDegrees) precision: 0.0001).
113+
self assert: (absolute longitudeInDegrees closeTo: (reference longitudeInDegrees) precision: 0.0001).
114+
]
115+
116+
{ #category : #tests }
117+
GeoViewMercatorProjectionTest >> testProjLatLonToCart [
118+
119+
"Brest"
120+
| coord cart |
121+
coord := AbsoluteCoordinates frBrest.
122+
cart := projection projLatLonToCart: coord.
123+
self assert: (cart xInMeters closeTo: -499082 precision: 1).
124+
self assert: (cart yInMeters closeTo: 6203898 precision: 1).
125+
self assert: (cart zInMeters closeTo: 52 precision: 0.01).
126+
127+
"Paris"
128+
coord := AbsoluteCoordinates frParis.
129+
cart := projection projLatLonToCart: coord.
130+
self assert: (cart xInMeters closeTo: 259745 precision: 1).
131+
self assert: (cart yInMeters closeTo: 6284473 precision: 1).
132+
self assert: (cart zInMeters closeTo: 79 precision: 0.01)
133+
]
134+
34135
{ #category : #'tests-accessing' }
35136
GeoViewMercatorProjectionTest >> testReverseProj [
36137

@@ -53,3 +154,40 @@ GeoViewMercatorProjectionTest >> testReverseProj [
53154
closeTo: absoluteCoordinates longitudeInDegrees
54155
precision: precision) ]
55156
]
157+
158+
{ #category : #tests }
159+
GeoViewMercatorProjectionTest >> testSideOfAbsoluteCoordinates [
160+
161+
self
162+
assert:
163+
(projection sideOfAbsoluteCoordinates: AbsoluteCoordinates zero)
164+
equals: GeoViewMapProjectionSide leftOfZeroMeridian.
165+
166+
self
167+
assert:
168+
(projection sideOfAbsoluteCoordinates: (AbsoluteCoordinates latitudeInDegrees: 0 longitudeInDegrees: -1))
169+
equals: GeoViewMapProjectionSide leftOfZeroMeridian.
170+
171+
self
172+
assert:
173+
(projection sideOfAbsoluteCoordinates: (AbsoluteCoordinates latitudeInDegrees: 0 longitudeInDegrees: 1))
174+
equals: GeoViewMapProjectionSide rightOfZeroMeridian.
175+
176+
"limits"
177+
self
178+
assert:
179+
(projection sideOfAbsoluteCoordinates: (AbsoluteCoordinates latitudeInDegrees: 90 longitudeInDegrees: 0))
180+
equals: GeoViewMapProjectionSide outsideLatitudeLimitTop.
181+
182+
self
183+
assert:
184+
(projection sideOfAbsoluteCoordinates: (AbsoluteCoordinates latitudeInDegrees: -90 longitudeInDegrees: 0))
185+
equals: GeoViewMapProjectionSide outsideLatitudeLimitBottom.
186+
187+
"out"
188+
self
189+
assert:
190+
(projection sideOfAbsoluteCoordinates: AbsoluteCoordinates new)
191+
equals: GeoViewMapProjectionSide outOfProjection
192+
.
193+
]

0 commit comments

Comments
 (0)