|
1 | 1 | import json |
2 | | -import random |
3 | 2 | import datetime |
4 | 3 | import psycopg2 |
5 | 4 | import logging |
6 | 5 | from functools import partial |
7 | 6 | from dateutil.parser import parse as dateparse |
8 | | -import pytz |
9 | 7 | from pygeoapi.util import format_datetime |
10 | 8 | from psycopg2.extras import Json, RealDictCursor, NamedTupleCursor |
11 | 9 | import re |
@@ -1168,61 +1166,64 @@ def _post_primal_members(self, collection_pk:int, feature_pk:int, layer_pk:int, |
1168 | 1166 | # If there is no 2D geometry but 3D, project 3D to 2D geometry |
1169 | 1167 | LOGGER.debug("Project geometry 3D to 2D ") |
1170 | 1168 | sql_project_shell = """ |
1171 | | -WITH faces AS ( |
1172 | | - SELECT |
1173 | | - c.id, |
1174 | | - s.shell_idx, |
1175 | | - f.face |
1176 | | - FROM cell_space_n_boundary c |
1177 | | - CROSS JOIN LATERAL jsonb_array_elements(c."3D_geometry"->'coordinates') |
1178 | | - WITH ORDINALITY AS s(shell, shell_idx) |
1179 | | - CROSS JOIN LATERAL jsonb_array_elements(s.shell) AS f(face) |
1180 | | - WHERE c."3D_geometry" IS NOT NULL |
1181 | | - AND c.type = 'space' |
1182 | | - AND c."2D_geometry" IS NULL |
1183 | | - AND c.thematiclayer_id = %s |
1184 | | -), |
1185 | | -proj AS ( |
1186 | | - SELECT |
1187 | | - id, |
1188 | | - shell_idx, |
1189 | | - ST_SetSRID( |
1190 | | - ST_Force2D( |
1191 | | - ST_GeomFromGeoJSON( |
1192 | | - jsonb_build_object( |
1193 | | - 'type', 'Polygon', |
1194 | | - 'coordinates', |
1195 | | - CASE |
1196 | | - -- if face is already [ring,...], keep it; else wrap to [ring] |
1197 | | - WHEN jsonb_typeof(face->0->0) = 'array' THEN face |
1198 | | - ELSE jsonb_build_array(face) |
1199 | | - END |
1200 | | - )::text |
1201 | | - ) |
1202 | | - ), |
1203 | | - 0 |
1204 | | - ) AS g2d |
1205 | | - FROM faces |
1206 | | -), |
1207 | | -u AS ( |
1208 | | - SELECT |
1209 | | - id, |
1210 | | - ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx = 1) ) AS ext2d, |
1211 | | - ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx > 1) ) AS int2d |
1212 | | - FROM proj |
1213 | | - GROUP BY id |
1214 | | -) |
1215 | | -UPDATE cell_space_n_boundary c |
1216 | | -SET "2D_geometry" = |
1217 | | - CASE |
1218 | | - WHEN u.int2d IS NULL THEN u.ext2d |
1219 | | - ELSE ST_Difference(u.ext2d, u.int2d) |
1220 | | - END |
1221 | | -FROM u |
1222 | | -WHERE c.id = u.id |
1223 | | - AND c.thematiclayer_id = %s; |
1224 | | -
|
1225 | | -""" |
| 1169 | + WITH faces AS ( |
| 1170 | + SELECT |
| 1171 | + c.id, |
| 1172 | + s.shell_idx, |
| 1173 | + f.face |
| 1174 | + FROM cell_space_n_boundary c |
| 1175 | + CROSS JOIN LATERAL jsonb_array_elements(c."3D_geometry"->'coordinates') |
| 1176 | + WITH ORDINALITY AS s(shell, shell_idx) |
| 1177 | + CROSS JOIN LATERAL jsonb_array_elements(s.shell) AS f(face) |
| 1178 | + WHERE c."3D_geometry" IS NOT NULL |
| 1179 | + AND c.type = 'space' |
| 1180 | + AND c."2D_geometry" IS NULL |
| 1181 | + AND c.thematiclayer_id = %s |
| 1182 | + AND ( |
| 1183 | + s.shell_idx = 1 |
| 1184 | + OR jsonb_array_length(c."3D_geometry"->'coordinates') > 1 |
| 1185 | + ) |
| 1186 | + ), |
| 1187 | + proj AS ( |
| 1188 | + SELECT |
| 1189 | + id, |
| 1190 | + shell_idx, |
| 1191 | + ST_SetSRID( |
| 1192 | + ST_Force2D( |
| 1193 | + ST_GeomFromGeoJSON( |
| 1194 | + jsonb_build_object( |
| 1195 | + 'type', 'Polygon', |
| 1196 | + 'coordinates', |
| 1197 | + CASE |
| 1198 | + -- if face is already [ring,...], keep it; else wrap to [ring] |
| 1199 | + WHEN jsonb_typeof(face->0->0) = 'array' THEN face |
| 1200 | + ELSE jsonb_build_array(face) |
| 1201 | + END |
| 1202 | + )::text |
| 1203 | + ) |
| 1204 | + ), |
| 1205 | + 0 |
| 1206 | + ) AS g2d |
| 1207 | + FROM faces |
| 1208 | + ), |
| 1209 | + u AS ( |
| 1210 | + SELECT |
| 1211 | + id, |
| 1212 | + ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx = 1) ) AS ext2d, |
| 1213 | + ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx > 1) ) AS int2d |
| 1214 | + FROM proj |
| 1215 | + GROUP BY id |
| 1216 | + ) |
| 1217 | + UPDATE cell_space_n_boundary c |
| 1218 | + SET "2D_geometry" = |
| 1219 | + CASE |
| 1220 | + WHEN u.int2d IS NULL THEN u.ext2d |
| 1221 | + ELSE ST_Difference(u.ext2d, u.int2d) |
| 1222 | + END |
| 1223 | + FROM u |
| 1224 | + WHERE c.id = u.id |
| 1225 | + AND c.thematiclayer_id = %s; |
| 1226 | + """ |
1226 | 1227 | cur.execute(sql_project_shell,(layer_pk,layer_pk)) |
1227 | 1228 |
|
1228 | 1229 | return dual_cell, dual_boundary |
@@ -1992,63 +1993,66 @@ def post_primal_member(self, collection_id:str, feature_id:str, layer_id:str, da |
1992 | 1993 |
|
1993 | 1994 | # project cellspace's 3D geometry to 2D if it has no 2D geometry. |
1994 | 1995 | LOGGER.debug("Project geometry 3D to 2D ") |
1995 | | - sql_projection = """ |
1996 | | -WITH faces AS ( |
1997 | | - SELECT |
1998 | | - c.id, |
1999 | | - s.shell_idx, |
2000 | | - f.face |
2001 | | - FROM cell_space_n_boundary c |
2002 | | - CROSS JOIN LATERAL jsonb_array_elements(c."3D_geometry"->'coordinates') |
2003 | | - WITH ORDINALITY AS s(shell, shell_idx) |
2004 | | - CROSS JOIN LATERAL jsonb_array_elements(s.shell) AS f(face) |
2005 | | - WHERE c."3D_geometry" IS NOT NULL |
2006 | | - AND c.type = 'space' |
2007 | | - AND c."2D_geometry" IS NULL |
2008 | | - AND c.id = %s |
2009 | | -), |
2010 | | -proj AS ( |
2011 | | - SELECT |
2012 | | - id, |
2013 | | - shell_idx, |
2014 | | - ST_SetSRID( |
2015 | | - ST_Force2D( |
2016 | | - ST_GeomFromGeoJSON( |
2017 | | - jsonb_build_object( |
2018 | | - 'type', 'Polygon', |
2019 | | - 'coordinates', |
2020 | | - CASE |
2021 | | - -- if face is already [ring,...], keep it; else wrap to [ring] |
2022 | | - WHEN jsonb_typeof(face->0->0) = 'array' THEN face |
2023 | | - ELSE jsonb_build_array(face) |
2024 | | - END |
2025 | | - )::text |
2026 | | - ) |
2027 | | - ), |
2028 | | - 0 |
2029 | | - ) AS g2d |
2030 | | - FROM faces |
2031 | | -), |
2032 | | -u AS ( |
2033 | | - SELECT |
2034 | | - id, |
2035 | | - ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx = 1) ) AS ext2d, |
2036 | | - ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx > 1) ) AS int2d |
2037 | | - FROM proj |
2038 | | - GROUP BY id |
2039 | | -) |
2040 | | -UPDATE cell_space_n_boundary c |
2041 | | -SET "2D_geometry" = |
2042 | | - CASE |
2043 | | - WHEN u.int2d IS NULL THEN u.ext2d |
2044 | | - ELSE ST_Difference(u.ext2d, u.int2d) |
2045 | | - END |
2046 | | -FROM u |
2047 | | -WHERE c.id = u.id |
2048 | | - AND c.id = %s; |
2049 | | -
|
2050 | | -""" |
2051 | | - cur.execute(sql_projection,(new_internal_id, new_internal_id)) |
| 1996 | + sql_project_shell = """ |
| 1997 | + WITH faces AS ( |
| 1998 | + SELECT |
| 1999 | + c.id, |
| 2000 | + s.shell_idx, |
| 2001 | + f.face |
| 2002 | + FROM cell_space_n_boundary c |
| 2003 | + CROSS JOIN LATERAL jsonb_array_elements(c."3D_geometry"->'coordinates') |
| 2004 | + WITH ORDINALITY AS s(shell, shell_idx) |
| 2005 | + CROSS JOIN LATERAL jsonb_array_elements(s.shell) AS f(face) |
| 2006 | + WHERE c."3D_geometry" IS NOT NULL |
| 2007 | + AND c.type = 'space' |
| 2008 | + AND c."2D_geometry" IS NULL |
| 2009 | + AND c.thematiclayer_id = %s |
| 2010 | + AND ( |
| 2011 | + s.shell_idx = 1 |
| 2012 | + OR jsonb_array_length(c."3D_geometry"->'coordinates') > 1 |
| 2013 | + ) |
| 2014 | + ), |
| 2015 | + proj AS ( |
| 2016 | + SELECT |
| 2017 | + id, |
| 2018 | + shell_idx, |
| 2019 | + ST_SetSRID( |
| 2020 | + ST_Force2D( |
| 2021 | + ST_GeomFromGeoJSON( |
| 2022 | + jsonb_build_object( |
| 2023 | + 'type', 'Polygon', |
| 2024 | + 'coordinates', |
| 2025 | + CASE |
| 2026 | + -- if face is already [ring,...], keep it; else wrap to [ring] |
| 2027 | + WHEN jsonb_typeof(face->0->0) = 'array' THEN face |
| 2028 | + ELSE jsonb_build_array(face) |
| 2029 | + END |
| 2030 | + )::text |
| 2031 | + ) |
| 2032 | + ), |
| 2033 | + 0 |
| 2034 | + ) AS g2d |
| 2035 | + FROM faces |
| 2036 | + ), |
| 2037 | + u AS ( |
| 2038 | + SELECT |
| 2039 | + id, |
| 2040 | + ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx = 1) ) AS ext2d, |
| 2041 | + ST_UnaryUnion( ST_Collect(g2d) FILTER (WHERE shell_idx > 1) ) AS int2d |
| 2042 | + FROM proj |
| 2043 | + GROUP BY id |
| 2044 | + ) |
| 2045 | + UPDATE cell_space_n_boundary c |
| 2046 | + SET "2D_geometry" = |
| 2047 | + CASE |
| 2048 | + WHEN u.int2d IS NULL THEN u.ext2d |
| 2049 | + ELSE ST_Difference(u.ext2d, u.int2d) |
| 2050 | + END |
| 2051 | + FROM u |
| 2052 | + WHERE c.id = u.id |
| 2053 | + AND c.thematiclayer_id = %s; |
| 2054 | + """ |
| 2055 | + cur.execute(sql_project_shell,(new_internal_id, new_internal_id)) |
2052 | 2056 | # 4. FIX: Commit only if we get here successfully |
2053 | 2057 | self.connection.commit() |
2054 | 2058 | return new_str_id |
|
0 commit comments