.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/quadkey_s2_example.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_quadkey_s2_example.py: Quadkey and S2 Grid Systems Demonstration. ========================================== This example showcases the new Quadkey and S2 grid systems added to M3S, demonstrating their unique properties and use cases. .. GENERATED FROM PYTHON SOURCE LINES 8-341 .. image-sg:: /auto_examples/images/sphx_glr_quadkey_s2_example_001.png :alt: Quadkey vs S2 Grid Systems - Manhattan, Quadkey Grid Level 14 (15 cells), S2 Grid Level 16 (16 cells), Overlay Comparison :srcset: /auto_examples/images/sphx_glr_quadkey_s2_example_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none M3S: Quadkey and S2 Grid Systems Advanced Spatial Indexing Demonstration ============================================================ QUADKEY GRID SYSTEM DEMONSTRATION ============================================================ Test point: New York City (40.7128, -74.006) Quadkey properties at different levels: /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:32: DeprecationWarning: The 'level' parameter is deprecated. Use 'precision' instead. grid = QuadkeyGrid(level=level) Level 8: Quadkey='03201011' | Size~1.0702deg x 1.4062deg | Length=8 Level 12: Quadkey='032010110301' | Size~0.0667deg x 0.0879deg | Length=12 Level 16: Quadkey='0320101103011111' | Size~0.0042deg x 0.0055deg | Length=16 Quadkey Hierarchical Properties: /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:48: DeprecationWarning: The 'level' parameter is deprecated. Use 'precision' instead. grid = QuadkeyGrid(level=12) Parent cell: 032010110301 Children: ['0320101103010', '0320101103011', '0320101103012', '0320101103013'] Children start with parent quadkey: True Number of neighbors: 8 ============================================================ S2 GRID SYSTEM DEMONSTRATION ============================================================ Test point: New York City (40.7128, -74.006) S2 properties at different levels: Level 8: Token='89c25' | Area~0.11912978deg | Token Length=5 Level 12: Token='89c25a3' | Area~0.00046488deg | Token Length=7 Level 16: Token='89c25a221' | Area~0.00000182deg | Token Length=9 S2 Hierarchical Properties: Cell token: 89c25a3 Number of children: 4 Sample child tokens: ['89c25a24', '89c25a2c'] Parent token: 89c25a4 Number of neighbors: 4 ============================================================ QUADKEY vs S2 COMPARISON ============================================================ /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:141: DeprecationWarning: The 'level' parameter is deprecated. Use 'precision' instead. quadkey_grid = QuadkeyGrid(level=14) # ~600m tiles /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:142: DeprecationWarning: The 'level' parameter is deprecated. Use 'precision' instead. s2_grid = S2Grid(level=12) # ~300m cells Processing intersections... Quadkey (level 14): 15 cells S2 (level 16): 16 cells /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:210: UserWarning: Legend does not support handles for PatchCollection instances. See: https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html#implementing-a-custom-legend-handler ax3.legend() /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:210: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. ax3.legend() ============================================================ SPATIAL PROPERTIES ANALYSIS ============================================================ Analyzing grid cell identifiers for global points: ------------------------------------------------------------ /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:236: DeprecationWarning: The 'level' parameter is deprecated. Use 'precision' instead. quadkey_grid = QuadkeyGrid(level=10) /home/runner/work/m3s/m3s/examples/quadkey_s2_example.py:237: DeprecationWarning: The 'level' parameter is deprecated. Use 'precision' instead. s2_grid = S2Grid(level=10) New York | Quadkey: 0320101103 | S2: 89c25b | QK Area: 0.093870 | S2 Area: 0.007442 London | Quadkey: 0313131311 | S2: 487605 | QK Area: 0.076926 | S2 Area: 0.007898 Tokyo | Quadkey: 1330021123 | S2: 6018f3 | QK Area: 0.100491 | S2 Area: 0.005990 Sydney | Quadkey: 3112301330 | S2: 6b12af | QK Area: 0.102622 | S2 Area: 0.007633 Mexico City | Quadkey: 0233100332 | S2: 85d1ff | QK Area: 0.116523 | S2 Area: 0.008349 ============================================================ USE CASE DEMONSTRATIONS ============================================================ 1. Quadkey Use Cases: - Web mapping and tile serving (Bing Maps) - Hierarchical spatial indexing - Database optimization with string keys - Cache-friendly tile loading - Simple spatial queries 2. S2 Use Cases: - Large-scale geospatial analysis (Google Maps) - Global spatial indexing - Spherical geometry calculations - Location-based services - Scientific geospatial applications 3. Performance Characteristics: Quadkey: - Fast string-based operations - Efficient for rectangular regions - Simple hierarchy traversal - Good for web applications S2: - Optimal spatial locality - Excellent for spherical calculations - Complex but powerful covering algorithms - Best for large-scale scientific applications ============================================================ SUMMARY ============================================================ + Quadkey Grid System: Microsoft's tile-based spatial indexing + S2 Grid System: Google's spherical geometry library + Both systems offer unique advantages for different applications + M3S provides unified interface for both systems Installation Notes: - Quadkey: No additional dependencies (pure Python implementation) - S2: Optional s2sphere library for full functionality - Install with: pip install s2sphere - Falls back to simplified implementation if not available | .. code-block:: Python import warnings import geopandas as gpd import matplotlib.pyplot as plt from shapely.geometry import box from m3s import QuadkeyGrid, S2Grid def demonstrate_quadkey(): """Demonstrate Quadkey grid system features.""" print("=" * 60) print("QUADKEY GRID SYSTEM DEMONSTRATION") print("=" * 60) # Create Quadkey grids at different levels levels = [8, 12, 16] test_point = (40.7128, -74.0060) # NYC print(f"Test point: New York City {test_point}") print("\nQuadkey properties at different levels:") for level in levels: grid = QuadkeyGrid(level=level) cell = grid.get_cell_from_point(test_point[0], test_point[1]) # Calculate approximate cell size bounds = grid.get_quadkey_bounds(cell.identifier) lat_size = bounds[2] - bounds[0] # max_lat - min_lat lon_size = bounds[3] - bounds[1] # max_lon - min_lon print( f" Level {level:2d}: Quadkey='{cell.identifier}' | " f"Size~{lat_size:.4f}deg x {lon_size:.4f}deg | " f"Length={len(cell.identifier)}" ) # Demonstrate hierarchical properties print("\nQuadkey Hierarchical Properties:") grid = QuadkeyGrid(level=12) cell = grid.get_cell_from_point(test_point[0], test_point[1]) print(f"Parent cell: {cell.identifier}") # Get children children = grid.get_children(cell) print(f"Children: {[child.identifier for child in children]}") # Show that children start with parent quadkey children_match = all( child.identifier.startswith(cell.identifier) for child in children ) print(f"Children start with parent quadkey: {children_match}") # Get neighbors neighbors = grid.get_neighbors(cell) print(f"Number of neighbors: {len(neighbors)}") return grid, cell def demonstrate_s2(): """Demonstrate S2 grid system features.""" print("\n" + "=" * 60) print("S2 GRID SYSTEM DEMONSTRATION") print("=" * 60) # Suppress warnings for cleaner output with warnings.catch_warnings(): warnings.simplefilter("ignore") # Create S2 grids at different levels levels = [8, 12, 16] test_point = (40.7128, -74.0060) # NYC print(f"Test point: New York City {test_point}") print("\nS2 properties at different levels:") cells_by_level = {} for level in levels: grid = S2Grid(level=level) cell = grid.get_cell_from_point(test_point[0], test_point[1]) cells_by_level[level] = cell # Calculate approximate cell area area = cell.polygon.area print( f" Level {level:2d}: Token='{cell.identifier}' | " f"Area~{area:.8f}deg | " f"Token Length={len(cell.identifier)}" ) # Demonstrate hierarchical properties print("\nS2 Hierarchical Properties:") grid = S2Grid(level=12) cell = grid.get_cell_from_point(test_point[0], test_point[1]) print(f"Cell token: {cell.identifier}") # Get children children = grid.get_children(cell) print(f"Number of children: {len(children)}") if children: child_ids = [child.identifier for child in children[:2]] print(f"Sample child tokens: {child_ids}") # Get parent parent = grid.get_parent(cell) if parent: print(f"Parent token: {parent.identifier}") # Get neighbors neighbors = grid.get_neighbors(cell) print(f"Number of neighbors: {len(neighbors)}") return grid, cell def compare_grid_systems(): """Compare Quadkey and S2 grid systems side by side.""" print("\n" + "=" * 60) print("QUADKEY vs S2 COMPARISON") print("=" * 60) # Test area around Manhattan test_area = box(-74.02, 40.70, -73.98, 40.78) test_gdf = gpd.GeoDataFrame( {"name": ["Manhattan"]}, geometry=[test_area], crs="EPSG:4326" ) # Create grids with similar resolutions quadkey_grid = QuadkeyGrid(level=14) # ~600m tiles s2_grid = S2Grid(level=12) # ~300m cells print("Processing intersections...") # Get intersections with warnings.catch_warnings(): warnings.simplefilter("ignore") quadkey_result = quadkey_grid.intersects(test_gdf) s2_result = s2_grid.intersects(test_gdf) print(f"Quadkey (level 14): {len(quadkey_result)} cells") print(f"S2 (level 16): {len(s2_result)} cells") # Create visualization fig, axes = plt.subplots(1, 3, figsize=(18, 6)) fig.suptitle("Quadkey vs S2 Grid Systems - Manhattan", fontsize=16) # Plot Quadkey ax1 = axes[0] ax1.set_title(f"Quadkey Grid\nLevel 14 ({len(quadkey_result)} cells)") if len(quadkey_result) > 0: quadkey_result.plot( ax=ax1, facecolor="lightblue", edgecolor="blue", linewidth=0.5, alpha=0.7 ) test_gdf.plot(ax=ax1, facecolor="none", edgecolor="red", linewidth=2) ax1.set_xlabel("Longitude") ax1.set_ylabel("Latitude") ax1.grid(True, alpha=0.3) # Plot S2 ax2 = axes[1] ax2.set_title(f"S2 Grid\nLevel 16 ({len(s2_result)} cells)") if len(s2_result) > 0: s2_result.plot( ax=ax2, facecolor="lightgreen", edgecolor="green", linewidth=0.5, alpha=0.7 ) test_gdf.plot(ax=ax2, facecolor="none", edgecolor="red", linewidth=2) ax2.set_xlabel("Longitude") ax2.set_ylabel("Latitude") ax2.grid(True, alpha=0.3) # Plot overlay ax3 = axes[2] ax3.set_title("Overlay Comparison") if len(quadkey_result) > 0: quadkey_result.plot( ax=ax3, facecolor="lightblue", edgecolor="blue", linewidth=0.5, alpha=0.5, label="Quadkey", ) if len(s2_result) > 0: s2_result.plot( ax=ax3, facecolor="lightgreen", edgecolor="green", linewidth=0.5, alpha=0.5, label="S2", ) test_gdf.plot( ax=ax3, facecolor="none", edgecolor="red", linewidth=2, label="Test Area" ) ax3.set_xlabel("Longitude") ax3.set_ylabel("Latitude") ax3.grid(True, alpha=0.3) ax3.legend() plt.tight_layout() plt.show() return quadkey_result, s2_result def analyze_spatial_properties(): """Analyze spatial properties of different grid systems.""" print("\n" + "=" * 60) print("SPATIAL PROPERTIES ANALYSIS") print("=" * 60) # Test points around the world test_points = [ (40.7128, -74.0060, "New York"), (51.5074, -0.1278, "London"), (35.6762, 139.6503, "Tokyo"), (-33.8688, 151.2093, "Sydney"), (19.4326, -99.1332, "Mexico City"), ] print("Analyzing grid cell identifiers for global points:") print("-" * 60) quadkey_grid = QuadkeyGrid(level=10) s2_grid = S2Grid(level=10) results = [] for lat, lon, city in test_points: quadkey_cell = quadkey_grid.get_cell_from_point(lat, lon) with warnings.catch_warnings(): warnings.simplefilter("ignore") s2_cell = s2_grid.get_cell_from_point(lat, lon) results.append( { "city": city, "lat": lat, "lon": lon, "quadkey_id": quadkey_cell.identifier, "quadkey_area": quadkey_cell.polygon.area, "s2_id": s2_cell.identifier, "s2_area": s2_cell.polygon.area, } ) for result in results: print( f"{result['city']:12} | " f"Quadkey: {result['quadkey_id']:12} | " f"S2: {result['s2_id']:12} | " f"QK Area: {result['quadkey_area']:.6f} | " f"S2 Area: {result['s2_area']:.6f}" ) return results def demonstrate_use_cases(): """Demonstrate typical use cases for each grid system.""" print("\n" + "=" * 60) print("USE CASE DEMONSTRATIONS") print("=" * 60) print("1. Quadkey Use Cases:") print(" - Web mapping and tile serving (Bing Maps)") print(" - Hierarchical spatial indexing") print(" - Database optimization with string keys") print(" - Cache-friendly tile loading") print(" - Simple spatial queries") print("\n2. S2 Use Cases:") print(" - Large-scale geospatial analysis (Google Maps)") print(" - Global spatial indexing") print(" - Spherical geometry calculations") print(" - Location-based services") print(" - Scientific geospatial applications") print("\n3. Performance Characteristics:") print(" Quadkey:") print(" - Fast string-based operations") print(" - Efficient for rectangular regions") print(" - Simple hierarchy traversal") print(" - Good for web applications") print(" S2:") print(" - Optimal spatial locality") print(" - Excellent for spherical calculations") print(" - Complex but powerful covering algorithms") print(" - Best for large-scale scientific applications") def main(): """Run main demonstration.""" print("M3S: Quadkey and S2 Grid Systems") print("Advanced Spatial Indexing Demonstration") # Individual demonstrations quadkey_grid, quadkey_cell = demonstrate_quadkey() s2_grid, s2_cell = demonstrate_s2() # Comparative analysis quadkey_result, s2_result = compare_grid_systems() analyze_spatial_properties() # Use case explanation demonstrate_use_cases() print("\n" + "=" * 60) print("SUMMARY") print("=" * 60) print("+ Quadkey Grid System: Microsoft's tile-based spatial indexing") print("+ S2 Grid System: Google's spherical geometry library") print("+ Both systems offer unique advantages for different applications") print("+ M3S provides unified interface for both systems") print("\nInstallation Notes:") print("- Quadkey: No additional dependencies (pure Python implementation)") print("- S2: Optional s2sphere library for full functionality") print(" - Install with: pip install s2sphere") print(" - Falls back to simplified implementation if not available") if __name__ == "__main__": # Suppress matplotlib font warnings warnings.filterwarnings("ignore", category=UserWarning, module="matplotlib") main() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.764 seconds) .. _sphx_glr_download_auto_examples_quadkey_s2_example.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: quadkey_s2_example.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: quadkey_s2_example.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: quadkey_s2_example.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_