Ë
    Uçxjv+  ã                  óæ  — d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
mZ dZdZdZd	Zd
ZdZdddddddddddddddœZej'                  «       D � �ci c]  \  } }|| “Œ
 c}} Z ee«      Z eh d£«      Z eh d£«      Z eh d£«      Z eh d£«      Z eh d£«      ZdZdZdZdZdZ dZ!dZ" eh d£«      Z# ejH                  d «      Z%dZ&d!Z'd"Z(d#Z)d$d%jU                  e(«      › d&d%jU                  d'„ e(D «       «      › d(�Z+ ed)¬*«       G d+„ d,«      «       Z, e,d«      Z-d<d-„Z.d=d.„Z/d>d/„Z0d?d0„Z1d@d1„Z2dAd2„Z3dBd3„Z4dCd4„Z5	 	 	 	 	 	 	 	 dDd5„Z6dEd6„Z7dFd7„Z8	 	 	 	 	 	 	 	 dGd8„Z9dHd9„Z:dId:„Z;dJd;„Z<yc c}} w )KzJSchema, filtering and normalization helpers for NextLimit mobile datasets.é    )ÚannotationsN)ÚMappingÚSequence)Ú	dataclassé   u   Â© OpenStreetMap contributorszODbL-1.0z'https://www.openstreetmap.org/copyrighti€–˜ i   é   é   é   é   é   é   é   é	   é
   é   é   é   é   )ÚmotorwayÚmotorway_linkÚtrunkÚ
trunk_linkÚprimaryÚprimary_linkÚ	secondaryÚsecondary_linkÚtertiaryÚtertiary_linkÚunclassifiedÚresidentialÚliving_streetÚservice>   ÚnoÚprivateÚforestryÚmilitaryÚ	emergencyÚagricultural>   ÚyesÚdeliveryÚ	customersÚ
designatedÚ
permissiveÚdestination>   údrive-throughÚdrivewayÚparking_aisleÚemergency_access>   Ú1r)   Útrue>   Ú0r#   Úfalse>   ÚnoneÚwalkÚsignalsÚunknownÚimplicitÚunpostedÚvariablez.^([0-9]{1,3}(?:\.[0-9]+)?)\s*(mph|km/?h|kph)?$éú   )Ú
segment_idÚ
osm_way_idÚfrom_node_idÚ
to_node_idÚ	directionÚlength_metersÚgeometryÚ
road_classÚspeed_limit_kmhÚspeed_sourceÚspeed_confidenceÚ
road_flagsÚ	road_nameaþ  
CREATE TABLE dataset_metadata (
    schema_version INTEGER NOT NULL,
    dataset_id TEXT NOT NULL,
    country_code TEXT NOT NULL,
    region_code TEXT NOT NULL,
    source_file TEXT NOT NULL,
    source_timestamp TEXT NOT NULL,
    generated_at TEXT NOT NULL,
    min_lat_e7 INTEGER NOT NULL,
    max_lat_e7 INTEGER NOT NULL,
    min_lon_e7 INTEGER NOT NULL,
    max_lon_e7 INTEGER NOT NULL,
    segment_count INTEGER NOT NULL,
    osm_attribution TEXT NOT NULL,
    osm_license TEXT NOT NULL,
    osm_license_url TEXT NOT NULL
);

CREATE TABLE road_segments (
    row_id INTEGER PRIMARY KEY,
    segment_id TEXT NOT NULL UNIQUE,
    osm_way_id INTEGER NOT NULL,
    from_node_id INTEGER NOT NULL,
    to_node_id INTEGER NOT NULL,
    direction INTEGER NOT NULL CHECK (direction IN (-1, 1)),
    length_meters REAL NOT NULL CHECK (length_meters > 0),
    geometry BLOB NOT NULL,
    road_class INTEGER NOT NULL CHECK (road_class BETWEEN 1 AND 14),
    speed_limit_kmh INTEGER CHECK (speed_limit_kmh BETWEEN 5 AND 250),
    speed_source INTEGER NOT NULL CHECK (speed_source BETWEEN 0 AND 4),
    speed_confidence INTEGER NOT NULL CHECK (speed_confidence BETWEEN 0 AND 100),
    road_flags INTEGER NOT NULL DEFAULT 0,
    road_name TEXT,
    CHECK (
        (speed_limit_kmh IS NULL AND speed_source = 0 AND speed_confidence = 0)
        OR
        (speed_limit_kmh IS NOT NULL AND speed_source != 0 AND speed_confidence > 0)
    )
);

CREATE INDEX road_segments_from_node_idx ON road_segments(from_node_id);
CREATE INDEX road_segments_to_node_idx ON road_segments(to_node_id);
CREATE INDEX road_segments_way_idx ON road_segments(osm_way_id, direction);

CREATE VIRTUAL TABLE road_segment_rtree USING rtree_i32(
    row_id,
    min_lat_e7,
    max_lat_e7,
    min_lon_e7,
    max_lon_e7
);
z
INSERT INTO road_segments (z, z
)
VALUES (c              #  ó&   K  — | ]	  }d |› �–— Œ y­w)Ú:N© )Ú.0Úcolumns     ú,/project/tools/osm-dataset/dataset_schema.pyÚ	<genexpr>rR   „   s   è ø€ ÐCÑ.B F�Q�v�h”<Ñ.Bùs   ‚z)
T)Úfrozenc                  ó4   — e Zd ZU ded<   eZded<   dZded<   y)ÚNormalizedSpeedLimitú
int | NoneÚ	value_kmhÚintÚsourcer   Úconfidence_percentN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__ÚSPEED_SOURCE_UNKNOWNrY   rZ   rN   ó    rQ   rU   rU   ˆ   s   … àÓØ&€FˆCÓ&ØÐ˜Ôr`   rU   c                ó.   — | j                  t        «       y )N)ÚexecutescriptÚ
SCHEMA_SQL)Ú
connections    rQ   Úcreate_schemare   ’   s   € Ø×ÑœZÕ(r`   c                óV  — t        | «      dk  rt        d«      ‚t        | «      t        kD  rt        dt        › d�«      ‚t        | «      g}| D ]8  \  }}|j                  t	        |t
        z  «      t	        |t
        z  «      f«       Œ: t        j                  dt        |«      › d�g|¢­Ž S )Nr   z,a road geometry requires at least two pointsza road geometry cannot exceed z pointsÚ>Úi)ÚlenÚ
ValueErrorÚMAXIMUM_GEOMETRY_POINTSÚextendÚroundÚCOORDINATE_SCALEÚstructÚpack)ÚpointsÚvaluesÚlatitudeÚ	longitudes       rQ   Úencode_geometryru   –   s    € Ü
ˆ6ƒ{�Q‚ÜÐGÓHÐHÜ
ˆ6ƒ{Ô,Ò,ÜÐ9Ô:QÐ9RÐRYÐZÓ[Ð[Ü˜V›˜€FÛ%Ñˆ�)Ø�‰”u˜XÔ(8Ñ8Ó9¼5ÀÔM]ÑA]Ó;^Ð_Õ`ð  &ä�;‰;˜œ3˜v›;˜- qÐ)Ð3¨FÒ3Ð3r`   c                ó$  — t        j                  | d   «      }t        j                  |d   «      }t        j                  |d   | d   z
  «      }t        j                  |d   | d   z
  «      }t        j                  |dz  «      dz  t        j                  |«      t        j                  |«      z  t        j                  |dz  «      dz  z  z   }dt        j                  t        j
                  |«      t        j
                  d|z
  «      «      z  S )Nr   r   r   g    ®MhA)ÚmathÚradiansÚsinÚcosÚatan2Úsqrt)ÚfirstÚsecondÚfirst_latitudeÚsecond_latitudeÚlatitude_deltaÚlongitude_deltaÚvalues          rQ   Úhaversine_metersr„   ¡   sß   € Ü—\‘\ %¨¡(Ó+€NÜ—l‘l 6¨!¡9Ó-€OÜ—\‘\ &¨¡)¨e°A©hÑ"6Ó7€NÜ—l‘l 6¨!¡9¨u°Q©xÑ#7Ó8€Oä�‰� !Ñ#Ó$¨Ñ)Ü
�(‰(�>Ó
"¤T§X¡X¨oÓ%>Ñ
>ÄÇÁÈ/Ð\]ÑJ]ÓA^ÐbcÑAcÑ
cñ	dð 
ð œTŸZ™Z¬¯	©	°%Ó(8¼$¿)¹)ÀAÈÁIÓ:NÓOÑOÐOr`   c                óÞ  — | j                  dd«      j                  «       j                  «       }|t        vry|dk(  r5| j                  dd«      j                  «       j                  «       t        v rydD ]D  }| j                  |d«      j                  «       j                  «       }|t
        v r y|t        v sŒD y | j                  dd«      j                  «       j                  «       t        vS )NÚhighwayÚ Fr"   )ÚmotorcarÚmotor_vehicleTÚaccess)ÚgetÚstripÚlowerÚDRIVABLE_HIGHWAYSÚEXCLUDED_SERVICE_TYPESÚALLOWED_ACCESSÚRESTRICTED_ACCESS)Útagsr†   Úkeyrƒ   s       rQ   Úis_drivabler”   ­   sÎ   € Ø�h‰h�y "Ó%×+Ñ+Ó-×3Ñ3Ó5€GØÔ'Ñ'ØØ�)Ò §¡¨°BÓ 7× =Ñ =Ó ?× EÑ EÓ GÔKaÑ aØÛ,ˆØ—‘˜˜bÓ!×'Ñ'Ó)×/Ñ/Ó1ˆØ”NÑ"ÙØÔ%Ò%Ùð -ð �8‰8�H˜bÓ!×'Ñ'Ó)×/Ñ/Ó1Ô9JÐJÐJr`   c                ó  — | j                  dd«      j                  «       j                  «       }|dk(  ry|t        v ry|t        v ry| j                  dd«      j                  «       dk(  s#| j                  d	d«      j                  «       d
k(  ryy)NÚonewayr‡   z-1)éÿÿÿÿ)r   )r   r—   ÚjunctionÚ
roundaboutr†   r   )r‹   rŒ   r�   ÚTRUE_ONEWAYÚFALSE_ONEWAY)r’   r–   s     rQ   Úallowed_directionsrœ   ¼   s‚   € Ø�X‰X�h Ó#×)Ñ)Ó+×1Ñ1Ó3€FØ�‚~ØØ”ÑØØ”ÑØØ‡x�x�
˜BÓ×%Ñ%Ó'¨<Ò7¸4¿8¹8ÀIÈrÓ;R×;XÑ;XÓ;ZÐ^hÒ;hØØr`   c                ó¾   — d}t        t        | «      «      dk(  r	|t        z  }| j                  dd«      j	                  «       j                  «       dk(  r	|t        z  }|S )Nr   r   r˜   r‡   r™   )ri   rœ   ÚROAD_FLAG_ONEWAYr‹   rŒ   r�   ÚROAD_FLAG_ROUNDABOUT)r’   rƒ   s     rQ   rJ   rJ   É   sZ   € Ø€EÜ
Ô˜dÓ#Ó$¨Ò)ØÔ!Ñ!ˆØ‡x�x�
˜BÓ×%Ñ%Ó'×-Ñ-Ó/°<Ò?ØÔ%Ñ%ˆØ€Lr`   c                óŽ   — 	 t         | j                  «       j                  «          S # t        $ r}t	        d| › �«      |‚d }~ww xY w)Nzunsupported road class: )ÚROAD_CLASS_CODESrŒ   r�   ÚKeyErrorrj   )r†   Úerrors     rQ   Úroad_class_coder¤   Ò   sI   € ðJÜ §¡£× 5Ñ 5Ó 7Ñ8Ð8øÜò JÜÐ3°G°9Ð=Ó>ÀEÐIûðJús   ‚$' §	A°?¿Ac                ód   — dD ]+  }| j                  |d«      j                  «       }|sŒ&|d d c S  y )N)ÚnameÚrefr‡   é    )r‹   rŒ   )r’   r“   rƒ   s      rQ   Ú
road_labelr©   Ù   s9   € ÛˆØ—‘˜˜bÓ!×'Ñ'Ó)ˆÚØ˜˜#�;Òð ð r`   c                óz  — |dk(  rdnd}| j                  |d«      j                  «       }|rt        ||t        «      S | j                  dd«      j                  «       }|rt        ||t        «      S dD ]$  }t        || j                  |d«      «      }|€Œ"|c S  t        || j                  dd«      «      xs t        S )Nr   zmaxspeed:forwardzmaxspeed:backwardr‡   Úmaxspeed)zzone:maxspeedzmaxspeed:typezsource:maxspeedr†   )r‹   rŒ   Ú_resolve_tagged_valueÚSPEED_SOURCE_OSM_DIRECTIONALÚSPEED_SOURCE_OSM_EXPLICITÚ_country_ruleÚ_legal_defaultÚUNKNOWN_SPEED_LIMIT)r’   Úcountry_coderC   Údirectional_keyÚdirectional_valueÚexplicit_valuer“   Úrules           rQ   Úresolve_speed_limitr·   á   sÊ   € ð
 -6¸ªNÑ(Ð@S€OØŸ™ °"Ó5×;Ñ;Ó=ÐÙÜ$ØØÜ(ó
ð 	
ð —X‘X˜j¨"Ó-×3Ñ3Ó5€NÙÜ$ØØÜ%ó
ð 	
ó EˆÜ˜\¨4¯8©8°C¸Ó+<Ó=ˆØÑØŠKð Eô
 ˜,¨¯©°¸BÓ(?Ó@ÒWÔDWÐWr`   c                óR  — | j                  «       j                  «       }d|v s|t        v ry t        j	                  |«      }|€y t        |j                  d«      «      }t        |«      }|j                  d«      dk(  rt        |dz  «      n|}|t        t        t        dz   «      vry |S )NÚ;r   r   Úmphg 8€~ß¿ù?)rŒ   r�   ÚUNKNOWN_MAXSPEED_VALUESÚSPEED_PATTERNÚ	fullmatchÚfloatÚgroupÚ_round_positiveÚrangeÚMINIMUM_SUPPORTED_SPEED_KPHÚMAXIMUM_SUPPORTED_SPEED_KPH)Ú	raw_valueÚ
normalizedÚmatchÚnumeric_valueÚrounded_valueÚ	speed_kmhs         rQ   Úparse_speed_kmhrÊ   ÿ   sŸ   € Ø—‘Ó"×(Ñ(Ó*€JØ
ˆjÑ˜JÔ*AÑAØÜ×#Ñ# JÓ/€EØ€}ØÜ˜%Ÿ+™+ a›.Ó)€MÜ# MÓ2€MØ=B¿[¹[È»^ÈuÒ=T” °Ñ 8Ô9ÐZg€IØœÔ9Ô;VÐYZÑ;ZÓ[Ñ[ØØÐr`   c           
     óÒ  — | j                  t        |«      }t        |j                  «      }|d   }t	        |t
        «      st        d«      ‚|D �cg c]   }t        t        |d   «      t        z  «      ‘Œ" }}|D �cg c]   }t        t        |d   «      t        z  «      ‘Œ" }}| j                  d|t        |«      t        |«      t        |«      t        |«      f«       |S c c}w c c}w )Nrq   z$points must be a coordinate sequencer   r   z5INSERT INTO road_segment_rtree VALUES (?, ?, ?, ?, ?))ÚexecuteÚINSERT_SEGMENT_SQLrX   Ú	lastrowidÚ
isinstancer   Ú	TypeErrorrm   r¾   rn   ÚminÚmax)rd   rr   ÚcursorÚrow_idrq   ÚpointÚ	latitudesÚ
longitudess           rQ   Úinsert_segmentrØ     sÒ   € Ø×ÑÔ 2°FÓ;€FÜ�×!Ñ!Ó"€FØ�HÑ€FÜ�fœhÔ'ÜÐ>Ó?Ð?ÙHNÓOÉ¸u””u˜U 1™X“Ô)9Ñ9Õ:È€IÐOÙIOÓPÉÀ”%œ˜e A™h›Ô*:Ñ:Õ;È€JÐPØ×ÑØ?Ø	”�Y“¤ Y£´°Z³Ä#ÀjÃ/ÐRôð €Mùò PùÚPs   Á%CÁ;%C$c                ó^   — t        | «      }|�t        ||d«      S t        || «      xs t        S )Néc   )rÊ   rU   r¯   r±   )rÄ   r²   Únumeric_sourceÚnumerics       rQ   r¬   r¬     s6   € ô
 ˜iÓ(€GØÐÜ# G¨^¸RÓ@Ð@Ü˜ yÓ1ÒHÔ5HÐHr`   c                ót  — |j                  «       j                  «       }|sy | j                  «       }|j                  |j                  «       › d�«      }|dk(  r|j                  d«      }dddddd	d
œ}n|dk(  rddddœ}n|dk(  rdddddœ}ny |j	                  |«      }|€d S t        |d   t        |d   «      S )NrM   ÚFRÚzone)é   éZ   )é   rá   )râ   éR   )é2   rã   )é‚   rã   )éP   éD   )Ú30Ú20r!   Úurbanr   ÚruralÚBE)éx   rã   )Úzone30rè   r   ÚDE)éd   rã   )rî   rè   rê   rë   r   r   )rŒ   r�   ÚupperÚremoveprefixr‹   rU   ÚSPEED_SOURCE_OSM_RULE)r²   rÄ   ÚrawÚcountryrÅ   ÚrulesÚresolveds          rQ   r¯   r¯   (  sÛ   € Ø
�/‰/Ó
×
!Ñ
!Ó
#€CÙØØ× Ñ Ó"€GØ×!Ñ! W§]¡]£_Ð$5°QÐ"7Ó8€JØ�$‚Ø×,Ñ,¨VÓ4ˆ
àØØ%ØØ!Øñ
‰ð 
�DŠØ#¨8ÀÑK‰Ø	�DŠØ#¨8¸hÐQZÑ[‰àØ�y‰y˜Ó$€HØÐ#ˆ4ÐnÔ)=¸hÀq¹kÔK`ÐbjÐklÑbmÓ)nÐnr`   c                ó¶   — | j                  «       |j                  «       j                  «       f}ddddœ}|j                  |«      }|€d S t	        |t
        d«      S )Nrå   râ   rí   ))rÞ   r   )rÞ   r!   )rì   r   é7   )rñ   rŒ   r�   r‹   rU   ÚSPEED_SOURCE_LEGAL_DEFAULT)r²   r†   r“   rö   rƒ   s        rQ   r°   r°   B  s^   € Ø×ÑÓ §¡£×!6Ñ!6Ó!8Ð
9€CàØ!#Øñ€Eð
 �I‰I�c‹N€EØ�=ˆ4ÐaÔ&:¸5ÔB\Ð^`Ó&aÐar`   c                ó2   — t        j                  | dz   «      S )Ng      à?)rw   Úfloor)rƒ   s    rQ   rÀ   rÀ   M  s   € Ü�:‰:�e˜c‘kÓ"Ð"r`   )rd   úsqlite3.ConnectionÚreturnÚNone)rq   zSequence[tuple[float, float]]rþ   Úbytes)r}   útuple[float, float]r~   r  rþ   r¾   )r’   úMapping[str, str]rþ   Úbool)r’   r  rþ   ztuple[int, ...])r’   r  rþ   rX   )r†   Ústrrþ   rX   )r’   r  rþ   z
str | None)r’   r  r²   r  rC   rX   rþ   rU   )rÄ   r  rþ   rV   )rd   rý   rr   zdict[str, object]rþ   rX   )rÄ   r  r²   r  rÛ   rX   rþ   rU   )r²   r  rÄ   r  rþ   úNormalizedSpeedLimit | None)r²   r  r†   r  rþ   r  )rƒ   r¾   rþ   rX   )=Ú__doc__Ú
__future__r   rw   ÚreÚsqlite3ro   Úcollections.abcr   r   Údataclassesr   ÚSCHEMA_VERSIONÚOSM_ATTRIBUTIONÚOSM_LICENSEÚOSM_LICENSE_URLrn   rk   r¡   ÚitemsÚROAD_CLASS_NAMESÚ	frozensetrŽ   r‘   r�   r�   rš   r›   rž   rŸ   r_   r®   r­   ró   rú   r»   Úcompiler¼   rÂ   rÃ   ÚROAD_SEGMENT_COLUMNSrc   ÚjoinrÍ   rU   r±   re   ru   r„   r”   rœ   rJ   r¤   r©   r·   rÊ   rØ   r¬   r¯   r°   rÀ   )r“   rƒ   s   00rQ   Ú<module>r     sV  ðá På "ã Û 	Û Û ß -Ý !à€Ø1€Ø€Ø;€ØÐ ØÐ ð ØØØØØØØØØØØØØñÐ ð  2B×1GÑ1GÔ1IÔJÑ1I¡: 3¨�E˜3‘JÐ1IÒJÐ ÙÐ.Ó/Ð áÒdÓeÐ ÙÒfÓg€Ù"Ò#eÓfÐ ÙÒ,Ó-€ÙÒ-Ó.€àÐ ØÐ àÐ ØÐ Ø Ð ØÐ ØÐ á#Ò$nÓoÐ Ø�—
‘
ÐLÓM€ØÐ Ø!Ð ðÐ ð 4€
ðlØ ŸI™IÐ&:Ó;Ð<ð =	Ø	�‰ÑCÑ.BÓCÓ	CÐDð EðÐ ñ �$Ô÷ ð  ó ð ñ +¨4Ó0Ð ó)ó4ó	PóKó
óóJóðXØ
ðXàðXð ðXð ó	Xó<óðIØðIàðIð ðIð ó	Ióoó4bô#ùóQ	 Ks   ÁE-