Class: GD::GIS::LayerGeoJSON
- Inherits:
-
Object
- Object
- GD::GIS::LayerGeoJSON
- Defined in:
- lib/gd/gis/layer_geojson.rb
Overview
Loads GeoJSON files into renderable Feature objects.
This class is responsible for:
-
Parsing GeoJSON files
-
Normalizing coordinates across CRS definitions
-
Classifying features using an ontology
-
Producing Feature instances
All coordinates are normalized to WGS84 in [longitude, latitude] order.
Class Method Summary collapse
-
.load(source) ⇒ Array<GD::GIS::Feature>
Loads a GeoJSON file and returns normalized features.
-
.normalize_geometry!(geometry, normalizer) ⇒ void
Normalizes a GeoJSON geometry in-place.
- .normalize_source(source) ⇒ Object
- .validate_geojson!(data) ⇒ Object
Class Method Details
.load(source) ⇒ Array<GD::GIS::Feature>
Loads a GeoJSON file and returns normalized features.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/gd/gis/layer_geojson.rb', line 28 def self.load(source) data = normalize_source(source) validate_geojson!(data) # 1) Detect CRS crs_name = data["crs"]&.dig("properties", "name") normalizer = CRS::Normalizer.new(crs_name) # 2) Load ontology ontology = Ontology.new # 3) Normalize geometries + classify data["features"].map do |feature| geometry = feature["geometry"] properties = feature["properties"] || {} raise ArgumentError, "Missing geometry" unless geometry raise ArgumentError, "Missing geometry type" unless geometry["type"] raise ArgumentError, "Missing coordinates" unless geometry["coordinates"] normalize_geometry!(geometry, normalizer) layer = ontology.classify( properties, geometry_type: geometry["type"] ) Feature.new(geometry, properties, layer) end end |
.normalize_geometry!(geometry, normalizer) ⇒ void
This method returns an undefined value.
Normalizes a GeoJSON geometry in-place.
Supports 2D and 3D coordinate arrays. Any additional dimensions (e.g. Z) are preserved or ignored depending on the CRS normalizer.
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/gd/gis/layer_geojson.rb', line 98 def self.normalize_geometry!(geometry, normalizer) case geometry["type"] when "Point" geometry["coordinates"] = normalizer.normalize(geometry["coordinates"]) when "LineString" geometry["coordinates"] = geometry["coordinates"].map { |c| normalizer.normalize(c) } when "MultiLineString" geometry["coordinates"] = geometry["coordinates"].map do |line| line.map { |c| normalizer.normalize(c) } end when "Polygon" geometry["coordinates"] = geometry["coordinates"].map do |ring| ring.map { |c| normalizer.normalize(c) } end when "MultiPolygon" geometry["coordinates"] = geometry["coordinates"].map do |poly| poly.map do |ring| ring.map { |c| normalizer.normalize(c) } end end end end |
.normalize_source(source) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/gd/gis/layer_geojson.rb', line 60 def self.normalize_source(source) case source when Hash source when String begin JSON.parse(source) rescue JSON::ParserError raise ArgumentError, "File not found: #{source}" unless File.exist?(source) JSON.parse(File.read(source)) end else raise ArgumentError, "Unsupported GeoJSON source: #{source.class}" end end |
.validate_geojson!(data) ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/gd/gis/layer_geojson.rb', line 79 def self.validate_geojson!(data) raise ArgumentError, "GeoJSON must be an object" unless data.is_a?(Hash) raise ArgumentError, "Only FeatureCollection is supported" unless data["type"] == "FeatureCollection" return if data["features"].is_a?(Array) raise ArgumentError, "GeoJSON must contain features array" end |