Coverage for gws-app/gws/gis/ms/_test/_test.py: 99%

137 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-16 23:09 +0200

1"""Tests for the MapServer module.""" 

2import gws 

3import gws.gis.ms as ms 

4from gws.test import util as u 

5import gws.lib.crs as crs 

6import gws.lib.image as image 

7 

8 

9def create_cross(): 

10 img = image.from_size((12, 12), color=(255, 255, 255, 255)) 

11 

12 block = image.from_size((4, 12), color=(0, 0, 0, 255)) 

13 img.paste(block, where=(4, 0)) 

14 

15 block = image.from_size((12, 4), color=(0, 0, 0, 255)) 

16 img.paste(block, where=(0, 4)) 

17 

18 output_path = f"/data/cross.png" 

19 img.to_path(str(output_path)) 

20 return output_path 

21 

22 

23def create_square(color, size, crs=None, pgw_str=None): 

24 if color == "red": 

25 c = (255, 0, 0, 125) 

26 elif color == "blue": 

27 c = (0, 0, 255, 125) 

28 else: 

29 c = (0, 255, 0, 125) 

30 img = image.from_size((size, size), color=(255, 255, 255, 255)) 

31 

32 block = image.from_size((size, size), color=c) 

33 

34 img.paste(block, where=(0, 0)) 

35 

36 output_path = f"/data/{color}_square_{crs}.png" 

37 img.to_path(str(output_path)) 

38 

39 if crs: 

40 with open(f"/data/{color}_square_{crs}.pgw", "w") as file: 

41 file.write(pgw_str) 

42 

43 with open(f"/data/{color}_square_{crs}.prj", "w") as file: 

44 file.write(f"""EPSG:{crs}""") 

45 return output_path 

46 

47 

48def red_square_4326(): 

49 return create_square("red", 100, 4326, "0.01\n0\n0\n-0.01\n5.005\n54.995") 

50 

51 

52def blue_square_4326(): 

53 return create_square("blue", 100, 4326, "0.01\n0\n0\n-0.01\n5.005\n54.995") 

54 

55 

56def red_square_3857(): 

57 return create_square("red", 100, 3857, "1113.194908\n0\n0\n-1113.194908\n557154.0514203343\n7360895.77546744") 

58 

59 

60def blue_square_3857(): 

61 return create_square("blue", 100, 3857, 

62 "1113.194908\n0\n0\n-1113.194908\n557154.0514203343\n7360895.77546744") 

63 

64 

65def test_rendering(): 

66 raster_image_path = create_square("red", 100) 

67 

68 map = ms.new_map() 

69 

70 map.add_layer( 

71 ms.LayerOptions(type=ms.LayerType.raster, 

72 path=str(raster_image_path), 

73 crs=crs.WEBMERCATOR 

74 ) 

75 ) 

76 

77 img = map.draw( 

78 bounds=gws.Bounds( 

79 extent=[0, 0, 100, 100], 

80 crs=crs.WEBMERCATOR, 

81 ), 

82 size=(100, 100), 

83 ) 

84 image_original = image.from_path("/gws-app/gws/gis/ms/_test/red_square.png") 

85 

86 assert img.compare_to(image_original) < 0.01 

87 

88 

89def test_rendering_add_layer(): 

90 raster_image_path = create_square("red", 100) 

91 

92 map = ms.new_map() 

93 

94 map.add_layer_from_config(f''' 

95 LAYER 

96 TYPE RASTER 

97 STATUS ON 

98 DATA "{raster_image_path}" 

99 PROJECTION 

100 "init=epsg:3857" 

101 END 

102 END 

103 ''') 

104 

105 img = map.draw( 

106 bounds=gws.Bounds( 

107 extent=[0, 0, 100, 100], 

108 crs=crs.WEBMERCATOR, 

109 ), 

110 size=(100, 100), 

111 ) 

112 

113 image_original = image.from_path("/gws-app/gws/gis/ms/_test/red_square.png") 

114 

115 assert img.compare_to(image_original) < 0.01 

116 

117 

118def test_reprojecting(): 

119 map = ms.new_map() 

120 

121 # adjust image 

122 rsl_path = blue_square_4326() 

123 rsl_opt2 = ms.LayerOptions(type=ms.LayerType.raster, path=str(rsl_path), crs=crs.WGS84) 

124 map.add_layer(rsl_opt2) 

125 

126 # adjust image 

127 rsl_path = red_square_3857() 

128 rsl_opt = ms.LayerOptions(type=ms.LayerType.raster, path=str(rsl_path), crs=crs.WEBMERCATOR) 

129 map.add_layer(rsl_opt) 

130 

131 img = map.draw( 

132 bounds=gws.Bounds( 

133 extent=[(5.005 - 1) + 1, (54.995 - 1) - 1, (5.005 + 1) + 1, (54.995 + 1) - 1], 

134 crs=crs.WGS84, 

135 ), 

136 size=(200, 200), 

137 ) 

138 

139 image_original = image.from_path("/gws-app/gws/gis/ms/_test/overlay.png") 

140 

141 assert img.compare_to(image_original) < 0.01 

142 

143 

144def test_reprojecting_bottom_right(): 

145 map = ms.new_map() 

146 

147 # adjust image 

148 rsl_path = blue_square_4326() 

149 rsl_opt2 = ms.LayerOptions(type=ms.LayerType.raster, path=str(rsl_path), crs=crs.WGS84) 

150 map.add_layer(rsl_opt2) 

151 

152 # adjust image 

153 rsl_path = red_square_3857() 

154 rsl_opt = ms.LayerOptions(type=ms.LayerType.raster, path=str(rsl_path), crs=crs.WEBMERCATOR) 

155 map.add_layer(rsl_opt) 

156 

157 img = map.draw( 

158 bounds=gws.Bounds( 

159 extent=[(5.005 - 1), (54.995 - 1), (5.005 + 1), (54.995 + 1)], 

160 crs=crs.WGS84, 

161 ), 

162 size=(200, 200), 

163 ) 

164 

165 image_original = image.from_path("/gws-app/gws/gis/ms/_test/overlay_bottom_right.png") 

166 

167 assert img.compare_to(image_original) < 0.01 

168 

169 

170def test_reprojecting_crs(): 

171 map = ms.new_map() 

172 

173 # adjust image 

174 rsl_path = blue_square_3857() 

175 rsl_opt2 = ms.LayerOptions(type=ms.LayerType.raster, path=str(rsl_path), crs=crs.WEBMERCATOR) 

176 map.add_layer(rsl_opt2) 

177 

178 # adjust image 

179 rsl_path = red_square_4326() 

180 rsl_opt = ms.LayerOptions(type=ms.LayerType.raster, path=str(rsl_path), crs=crs.WGS84) 

181 map.add_layer(rsl_opt) 

182 

183 img = map.draw( 

184 bounds=gws.Bounds( 

185 extent=[(557154.0514203343 - 111319.4908) + 111319.4908, (7360895.77546744 - 111319.4908) - 111319.4908, 

186 (557154.0514203343 + 111319.4908) + 111319.4908, (7360895.77546744 + 111319.4908) - 111319.4908], 

187 # 557154.0514203343\n7360895.77546744 

188 crs=crs.WEBMERCATOR, 

189 ), 

190 size=(200, 200), 

191 ) 

192 image_original = image.from_path("/gws-app/gws/gis/ms/_test/reprojecting_crs.png") 

193 

194 assert img.compare_to(image_original) < 0.01 

195 

196 

197def test_vectors(): 

198 map = ms.new_map() 

199 

200 map.add_layer_from_config(''' 

201 LAYER 

202 TYPE LINE 

203 STATUS ON 

204 FEATURE 

205 POINTS 

206 751539 6669003 

207 751539 6672326 

208 755559 6672326 

209 751539 6669003 

210 END 

211 END 

212 CLASS 

213 STYLE 

214 COLOR 80 150 55 

215 WIDTH 5 

216 END 

217 END 

218 END 

219 ''') 

220 

221 img = map.draw( 

222 bounds=gws.Bounds( 

223 extent=[738040, 6653804, 765743, 6683686], 

224 crs=crs.WEBMERCATOR, 

225 ), 

226 size=(800, 600), 

227 ) 

228 

229 image_original = image.from_path("/gws-app/gws/gis/ms/_test/vectors.png") 

230 

231 assert img.compare_to(image_original) < 0.01 

232 

233 

234def test_geometry_style(): 

235 u.pg.create('test_table', 

236 {'id': 'int primary key', 'geom': 'geometry(LINESTRING, 4326)', 'label': 'text'}) 

237 

238 data = [ 

239 {'id': 4, 'geom': 'LINESTRING(0 -5,-10 0)', 'label': 'label 4'}, 

240 {'id': 5, 'geom': 'LINESTRING(0 0, 5 0, 2.5 5, 0 0)', 'label': 'label 5'} 

241 ] 

242 

243 u.pg.insert('test_table', data) 

244 

245 map = ms.new_map() 

246 

247 style_vals = gws.StyleValues(fill='blue', 

248 stroke='green', 

249 stroke_width=10, 

250 stroke_dasharray=[20, 40, -1], 

251 stroke_linejoin='miter', 

252 stroke_miterlimit=10, 

253 stroke_linecap='round', 

254 with_geometry='all', 

255 offset_x=10, 

256 offset_y=0, 

257 ) 

258 

259 vl_opts = ms.LayerOptions(type=ms.LayerType.line, 

260 connectionType="postgres", 

261 connectionString=u.pg.url(), 

262 crs=crs.WGS84, 

263 dataString="geom FROM test_table USING UNIQUE id USING SRID=4326", 

264 style=style_vals) 

265 

266 map.add_layer(vl_opts) 

267 

268 img = map.draw( 

269 bounds=gws.Bounds( 

270 extent=[-15, -10, 15, 10], 

271 crs=crs.WGS84, 

272 ), 

273 size=(800, 600), 

274 ) 

275 image_original = image.from_path("/gws-app/gws/gis/ms/_test/geometry_style.png") 

276 

277 assert img.compare_to(image_original) < 0.01 

278 

279 

280def test_label_style(): 

281 # setup and fill pg table with vectordata 

282 u.pg.create('test_table', {'id': 'int primary key', 'geom': 'geometry(POINT, 4326)', 'label': 'text'}) 

283 

284 data = [ 

285 {'id': 1, 'geom': 'POINT(0 0)', 'label': 'label 1'}, 

286 {'id': 2, 'geom': 'POINT(5 5)', 'label': 'label 2'} 

287 ] 

288 

289 u.pg.insert('test_table', data) 

290 

291 map = ms.new_map() 

292 

293 style_vals = gws.StyleValues(fill='blue', 

294 stroke='green', 

295 stroke_width=10, 

296 with_geometry='all', 

297 

298 with_label='all', 

299 label_align='left', 

300 label_background='red', 

301 label_fill='black', 

302 # label_font_family='sans', 

303 label_font_size=30, 

304 # label_font_style='italic', 

305 # label_font_weight='bold', 

306 # label_line_height=100, 

307 # label_min_scale=1000, 

308 # label_max_scale=10000, 

309 label_offset_x=10, 

310 label_offset_y=10, 

311 label_padding=[2, 3, 4, 5], 

312 label_placement='start', 

313 label_stroke='yellow', 

314 label_stroke_dasharray=[5, 10, -1], 

315 label_stroke_linecap='round', 

316 label_stroke_linejoin='miter', 

317 label_stroke_miterlimit=10, 

318 label_stroke_width=10, 

319 ) 

320 

321 vl_opts = ms.LayerOptions(type=ms.LayerType.point, 

322 connectionType="postgres", 

323 connectionString=u.pg.url(), 

324 crs=crs.WGS84, 

325 dataString="geom FROM test_table USING UNIQUE id USING SRID=4326", 

326 style=style_vals) 

327 

328 map.add_layer(vl_opts) 

329 

330 img = map.draw( 

331 bounds=gws.Bounds( 

332 extent=[-15, -10, 15, 10], 

333 crs=crs.WGS84, 

334 ), 

335 size=(800, 600), 

336 ) 

337 image_original = image.from_path("/gws-app/gws/gis/ms/_test/label_style.png") 

338 

339 assert img.compare_to(image_original) < 0.01 

340 

341 

342def test_marker_style(): 

343 u.pg.create('test_table', {'id': 'int primary key', 'geom': 'geometry(LINESTRING, 4326)'}) 

344 

345 data = [ 

346 {'id': 1, 'geom': 'LINESTRING(-10 0, 10 0)'}, 

347 {'id': 2, 'geom': 'LINESTRING(0 -5, 0 5)'} 

348 ] 

349 

350 u.pg.insert('test_table', data) 

351 

352 map = ms.new_map() 

353 

354 style_vals = gws.StyleValues(fill='blue', 

355 stroke='green', 

356 stroke_width=10, 

357 with_geometry='none', 

358 

359 marker='arrow', 

360 marker_fill='red', 

361 marker_stroke_dashoffset=-25, 

362 marker_stroke_linecap='round', 

363 marker_stroke_linejoin='miter', 

364 marker_stroke_miterlimit=10, 

365 marker_size=10 

366 ) 

367 

368 vl_opts = ms.LayerOptions(type=ms.LayerType.line, 

369 connectionType="postgres", 

370 connectionString=u.pg.url(), 

371 crs=crs.WGS84, 

372 dataString="geom FROM test_table USING UNIQUE id USING SRID=4326", 

373 style=style_vals) 

374 

375 map.add_layer(vl_opts) 

376 

377 img = map.draw( 

378 bounds=gws.Bounds( 

379 extent=[-15, -10, 15, 10], 

380 crs=crs.WGS84, 

381 ), 

382 size=(800, 600), 

383 ) 

384 image_original = image.from_path("/gws-app/gws/gis/ms/_test/marker_style.png") 

385 

386 assert img.compare_to(image_original) < 0.01 

387 

388 

389def test_icon(): 

390 create_cross() 

391 u.pg.create('test_table', {'id': 'int primary key', 'geom': 'geometry(POINT, 4326)', 'label': 'text'}) 

392 

393 data = [ 

394 {'id': 1, 'geom': 'POINT(0 0)', 'label': 'label 1'}, 

395 {'id': 2, 'geom': 'POINT(5 5)', 'label': 'label 2'} 

396 ] 

397 

398 u.pg.insert('test_table', data) 

399 

400 map = ms.new_map() 

401 

402 style_vals = gws.StyleValues(fill='blue', 

403 stroke='green', 

404 stroke_width=10, 

405 with_geometry='all', 

406 icon='/data/cross.png', 

407 

408 with_label='all', 

409 label_align='left', 

410 label_background='red', 

411 label_fill='black', 

412 # label_font_family='sans', 

413 label_font_size=30, 

414 # label_font_style='italic', 

415 # label_font_weight='bold', 

416 # label_line_height=100, 

417 # label_min_scale=1000, 

418 # label_max_scale=10000, 

419 label_offset_x=10, 

420 label_offset_y=10, 

421 label_padding=[2, 3, 4, 5], 

422 label_placement='start', 

423 label_stroke='yellow', 

424 label_stroke_dasharray=[5, 10, -1], 

425 label_stroke_linecap='round', 

426 label_stroke_linejoin='miter', 

427 label_stroke_miterlimit=10, 

428 label_stroke_width=10, 

429 ) 

430 

431 vl_opts = ms.LayerOptions(type=ms.LayerType.point, 

432 connectionType="postgres", 

433 connectionString=u.pg.url(), 

434 crs=crs.WGS84, 

435 dataString="geom FROM test_table USING UNIQUE id USING SRID=4326", 

436 style=style_vals) 

437 

438 map.add_layer(vl_opts) 

439 

440 img = map.draw( 

441 bounds=gws.Bounds( 

442 extent=[-15, -10, 15, 10], 

443 crs=crs.WGS84, 

444 ), 

445 size=(800, 600), 

446 ) 

447 image_original = image.from_path("/gws-app/gws/gis/ms/_test/icon.png") 

448 

449 assert img.compare_to(image_original) < 0.01