a
    !h                     @   s   d dl mZ d dlmZ d dlmZmZmZm	Z	m
Z
 G dd dZeddZeddZed	d
Zdd Zdd Zdd Zdd Zdd Zedkrd dlZd dlZe Zejddedd ejddedejd e Zeej Z ej!"e  dS )    )
namedtuple)vector_tile_pb2)CMD_LINE_TOCMD_MOVE_TO
LINESTRINGzig_zag_decodezig_zag_encodec                   @   s4   e Zd ZdZdd Zdd Zedd Zdd	 Zd
S )StringTableOptimisera  
    Optimizes the order of keys and values in the MVT layer string table.

    Counts the number of times an entry in the MVT string table (both keys and values) is used. Then reorders the
    string table to have the most commonly used entries first and updates the features to use the replacement
    locations in the table. This can save several percent in a tile with large numbers of features.
    c                 C   s   i | _ i | _d S N)
key_counts
val_counts)self r   i/var/www/staging/api/virtual_environments/venv/lib/python3.9/site-packages/mapbox_vector_tile/optimise.py__init__   s    zStringTableOptimiser.__init__c                 C   sP   t |}t||D ]8\}}| j|dd | j|< | j|dd | j|< qd S )Nr      )iterzipr   getr   )r   Zfeature_tagsitrkvr   r   r   add_tags   s    zStringTableOptimiser.add_tagsc           
      C   s   t tdd |  D dd}g }|D ]\}}|||  q&t|t|ksRJ |d d = || i }t|D ]\}\}}	|||	< qr|S )Nc                 s   s   | ]\}}||fV  qd S r
   r   ).0r   cr   r   r   	<genexpr>       z5StringTableOptimiser._update_table.<locals>.<genexpr>T)reverse)listsorteditemsappendlenextend	enumerate)
countstablesortZ	new_table_xZnew_indexesir   r   r   r   r   _update_table   s    


z"StringTableOptimiser._update_tablec                 C   sx   |  | j|j}|  | j|j}|jD ]L}tdt|jdD ]4}||j|  |j|< ||j|d   |j|d < q<q&d S )Nr      r   )	r+   r   keysr   valuesfeaturesranger"   tags)r   layerZnew_keynew_valfeaturer*   r   r   r   update_string_table2   s    
z(StringTableOptimiser.update_string_tableN)	__name__
__module____qualname____doc__r   r   staticmethodr+   r5   r   r   r   r   r	      s   
r	   MoveTozx yEndsAtLinezmoveto endsat cmdsc                 C   sx  g }g }d}d}d}t | }d}||k rL| | }|d@ }	|d }
|	tkr|rj|t|t||| g }|
dksvJ |t| |d  7 }|t| |d  7 }|d7 }t||}q |	tkr<|sJ |d |
d  }|| ||  t	d|
D ]D}t| |d d|   }t| |d d|   }||7 }||7 }q|}q t
d|	 q |rt|s\J |t|t||| |S )	z
    Decode a linear MVT geometry into a list of Lines.

    Each individual linestring in the MVT is extracted to a separate entry in the list of lines.
    Nr         r   r,      zUnhandled command: )r"   r   r!   r=   r<   r   r;   r   r#   r0   
ValueError)geomlinescurrent_lineZcurrent_movetor)   yendr*   headercmdZ
run_lengthZnext_ijdxdyr   r   r   _decode_linesG   sF    



rL   c                 C   s   d}d}g }| rd}d}t | D ]F\}}|\}}	}	t|j| t|j|  }
|du s^|
|k r |
}|}q |dustJ | |}|\}	}}	|j}|j}|| q|S )zk
    Reorder lines so that the distance from the end of one to the beginning of the next is minimized.
    r   N)r$   absr)   rE   popr!   )rC   r)   rE   	new_linesZmin_distZmin_ir*   linemovetor(   distendsatr   r   r   _reorder_lines   s&    


rT   c                 C   s   g }d}d}|D ]^}|\}}}|j | }	|j| }
|j }|j}|d |t|	 |t|
 || q| dd= | | dS )z
    Re-encode a list of Lines with absolute MoveTos as a continuous stream of MVT geometry commands, each relative to
    the last. Replace geom with that stream.
    r   	   N)r)   rE   r!   r   r#   )rB   rO   Znew_geomr)   rE   rP   rQ   rS   Zlineto_cmdsrJ   rK   r   r   r   _rewrite_geometry   s    




rV   c                 C   s*   t | }t|dkr&t|}t| | d S )Nr   )rL   r"   rT   rV   )rB   rC   r   r   r   optimise_multilinestring   s    rW   c                 C   sb   t  }||  |jD ]@}t }|jD ]$}|jtkr@t|j	 |
|j q(|| q| S )z
    Decode a sequence of bytes as an MVT tile and reorder the string table of its layers and the order of its
    multilinestrings to save a few bytes.
    )vector_tileZtileZParseFromStringZlayersr	   r/   typer   rW   Zgeometryr   r1   r5   ZSerializeToString)Z
tile_bytestr2   Zstor4   r   r   r   optimise_tile   s    




r[   __main__N
input_filezInput MVT filer)helprY   z--output-filezOutput file, default is stdoutw)r_   rY   default)#collectionsr   Zmapbox_vector_tile.Mapboxr   rX   Zmapbox_vector_tile.utilsr   r   r   r   r   r	   r;   r<   r=   rL   rT   rV   rW   r[   r6   argparsesysArgumentParserparseradd_argumentFileTypestdout
parse_argsargsr]   readZoutput_bytesZoutput_filewriter   r   r   r   <module>   s,   ;


>!