0001-opengis-add-preferred-projection-system-20826.patch
passerelle/apps/opengis/migrations/0004_auto_20180219_1613.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 |
from __future__ import unicode_literals |
|
3 | ||
4 |
from django.db import migrations, models |
|
5 | ||
6 | ||
7 |
class Migration(migrations.Migration): |
|
8 | ||
9 |
dependencies = [ |
|
10 |
('opengis', '0003_auto_20171220_1058'), |
|
11 |
] |
|
12 | ||
13 |
operations = [ |
|
14 |
migrations.AddField( |
|
15 |
model_name='opengis', |
|
16 |
name='projection', |
|
17 |
field=models.CharField(default=b'EPSG:3857', max_length=16, verbose_name='GIS projection', choices=[(b'EPSG:4326', 'EPSG:4326 (WGS 84)'), (b'EPSG:2154', 'EPSG:2154 (Lambert-93)'), (b'EPSG:3857', 'EPSG:3857 (WGS84 / Pseudo-Mercator)'), (b'EPSG:3945', 'EPSG:3945 (CC45)')]), |
|
18 |
), |
|
19 |
] |
passerelle/apps/opengis/models.py | ||
---|---|---|
43 | 43 |
d[attribute_name] = build_dict_from_xml(child) |
44 | 44 |
return d |
45 | 45 | |
46 |
PROJECTIONS = ( |
|
47 |
('EPSG:2154', _('EPSG:2154 (Lambert-93)')), |
|
48 |
('EPSG:3857', _('EPSG:3857 (WGS 84 / Pseudo-Mercator)')), |
|
49 |
('EPSG:3945', _('EPSG:3945 (CC45)')), |
|
50 |
('EPSG:4326', _('EPSG:4326 (WGS 84)')), |
|
51 |
) |
|
52 | ||
46 | 53 | |
47 | 54 |
class OpenGIS(BaseResource): |
48 | 55 |
category = _('Geographic information system') |
49 | 56 |
wms_service_url = models.URLField(_('Web Map Service (WMS) URL'), max_length=256, blank=True) |
50 | 57 |
wfs_service_url = models.URLField(_('Web Feature Service (WFS) URL'), max_length=256, blank=True) |
51 | 58 |
query_layer = models.CharField(_('Query Layer'), max_length=256) |
59 |
projection = models.CharField(_('GIS projection'), choices=PROJECTIONS, |
|
60 |
default='EPSG:3857', max_length=16) |
|
52 | 61 | |
53 | 62 |
class Meta: |
54 | 63 |
verbose_name = _('OpenGIS') |
... | ... | |
150 | 159 |
'lon': {'description': _('Longitude'), 'example_value': '4.78414'}, |
151 | 160 |
}) |
152 | 161 |
def feature_info(self, request, lat, lon): |
153 |
bbox = '%s,%s,%s,%s' % (lat, lon, float(lat) + 0.002, float(lon) + 0.002) |
|
162 |
lon_b, lat_b = float(lon) + 0.002, float(lat) + 0.002 |
|
163 |
if self.projection != 'EPSG:4326': |
|
164 |
wgs84 = pyproj.Proj(init='EPSG:4326') |
|
165 |
target_projection = pyproj.Proj(init=self.projection) |
|
166 |
lon_b, lat_b = pyproj.transform(wgs84, target_projection, lon_b, lat_b) |
|
167 |
lon, lat = pyproj.transform(wgs84, target_projection, lon, lat) |
|
168 |
bbox = '%s,%s,%s,%s' % (lat, lon, lat_b, lon_b) |
|
154 | 169 |
params = { |
155 | 170 |
'VERSION': '1.3.0', |
156 | 171 |
'SERVICE': 'WMS', |
... | ... | |
161 | 176 |
'J': '0', |
162 | 177 |
'HEIGHT': '500', |
163 | 178 |
'WIDTH': '500', |
164 |
'CRS': 'EPSG:4171',
|
|
179 |
'CRS': self.projection,
|
|
165 | 180 |
'LAYERS': self.query_layer, |
166 | 181 |
'QUERY_LAYERS': self.query_layer, |
167 | 182 |
'BBOX': bbox, |
... | ... | |
192 | 207 |
lat_deg = math.degrees(lat_rad) |
193 | 208 |
return (lon_deg, lat_deg) |
194 | 209 | |
195 |
wgs84 = pyproj.Proj(init='epsg:4326') |
|
196 |
epsg3857 = pyproj.Proj(init='epsg:3857') |
|
197 | 210 |
# lower left |
198 |
ll_lon, ll_lat = pyproj.transform(wgs84, epsg3857, *num2deg(tile_x, tile_y+1, zoom))
|
|
211 |
ll_lon, ll_lat = num2deg(tile_x, tile_y+1, zoom)
|
|
199 | 212 |
# upper right |
200 |
ur_lon, ur_lat = pyproj.transform(wgs84, epsg3857, *num2deg(tile_x+1, tile_y, zoom)) |
|
213 |
ur_lon, ur_lat = num2deg(tile_x+1, tile_y, zoom) |
|
214 | ||
215 |
# convert only when projection system is other than WGS84 |
|
216 |
if self.projection != 'EPSG:4326': |
|
217 |
wgs84 = pyproj.Proj(init='EPSG:4326') |
|
218 |
target_projection = pyproj.Proj(init=self.projection) |
|
219 |
ll_lon, ll_lat = pyproj.transform(wgs84, target_projection, ll_lon, ll_lat) |
|
220 |
ur_lon, ur_lat = pyproj.transform(wgs84, target_projection, ur_lon, ur_lat) |
|
221 | ||
201 | 222 |
bbox = '%s,%s,%s,%s' % (ll_lon, ll_lat, ur_lon, ur_lat) |
202 | 223 | |
203 | 224 |
params = { |
... | ... | |
210 | 231 |
'TRANSPARENT': 'false', |
211 | 232 |
'HEIGHT': '256', |
212 | 233 |
'WIDTH': '256', |
213 |
'SRS': 'EPSG:3857',
|
|
234 |
'SRS': self.projection,
|
|
214 | 235 |
'BBOX': bbox, |
215 | 236 |
} |
216 | 237 |
return HttpResponse( |
tests/test_opengis.py | ||
---|---|---|
130 | 130 |
assert endpoint == '/opengis/test/feature_info' |
131 | 131 |
mocked_get.return_value = utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200) |
132 | 132 |
resp = app.get(endpoint, params={'lat': '45.796890', 'lon': '4.784140'}) |
133 |
assert mocked_get.call_args[1]['params']['BBOX'] == '5747860.22776,532568.028684,5748179.56467,532790.667665' |
|
134 |
assert mocked_get.call_args[1]['params']['CRS'] == 'EPSG:3857' |
|
133 | 135 |
assert resp.json['data']['cad_cadastrecadparcelle_layer']['cad_cadastrecadparcelle_feature']['natureproprietaire'] == 'Particulier' |
136 |
connector.projection = 'EPSG:4326' |
|
137 |
connector.save() |
|
138 |
resp = app.get(endpoint, params={'lat': '45.796890', 'lon': '4.784140'}) |
|
139 |
assert mocked_get.call_args[1]['params']['BBOX'] == '45.796890,4.784140,45.79889,4.78614' |
|
140 |
assert mocked_get.call_args[1]['params']['CRS'] == 'EPSG:4326' |
|
134 | 141 | |
135 | 142 |
@mock.patch('passerelle.utils.Request.get') |
136 | 143 |
def test_tile(mocked_get, app, connector): |
... | ... | |
138 | 145 |
assert endpoint == '/opengis/test/tile' |
139 | 146 |
mocked_get.return_value = utils.FakedResponse(content='\x89PNG\r\n\x1a\n\x00\x00...', status_code=200) |
140 | 147 |
resp = app.get(endpoint + '/16/33650/23378.png') |
148 |
assert mocked_get.call_args[1]['params']['SRS'] == 'EPSG:3857' |
|
149 |
assert mocked_get.call_args[1]['params']['BBOX'] == '539339.67158,5741338.06856,539951.167806,5741949.56478' |
|
150 |
connector.projection = 'EPSG:4326' |
|
151 |
connector.save() |
|
152 |
resp = app.get(endpoint + '/16/33650/23378.png') |
|
153 |
assert mocked_get.call_args[1]['params']['SRS'] == 'EPSG:4326' |
|
154 |
assert mocked_get.call_args[1]['params']['BBOX'] == '4.84497070312,45.7560261559,4.85046386719,45.7598586879' |
|
141 | 155 |
assert resp.content == '\x89PNG\r\n\x1a\n\x00\x00...' |
142 | 156 | |
143 | 157 | |
144 |
- |