Module: NSWTopo::Feature
- Includes:
- Log, VectorRender
- Defined in:
- lib/nswtopo/layer/feature.rb
Constant Summary collapse
- CREATE =
%w[features]
Constants included from VectorRender
VectorRender::FONT_SCALED_ATTRIBUTES, VectorRender::MARGIN, VectorRender::SVG_ATTRIBUTES
Constants included from Log
Log::FAILURE, Log::NEUTRAL, Log::SUCCESS, Log::UPDATE
Instance Method Summary collapse
Methods included from VectorRender
#categorise, #create, #drawing_features, #features, #filename, #labeling_features, #params_for, #render, #to_s
Methods included from Log
#log_abort, #log_neutral, #log_success, #log_update, #log_warn
Instance Method Details
#get_features ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/nswtopo/layer/feature.rb', line 6 def get_features (Array === @features ? @features : [@features]).map do |args| case args when Hash then args.transform_keys(&:to_sym) when String then { source: args } else raise "#{@source.basename}: invalid or no features specified" end end.slice_before do |args| !args.delete(:fallback) end.map do |fallbacks| fallbacks.each.with_object({}) end.map do |fallbacks| args, = *fallbacks.next source, error = args.delete(:source), nil source = @path if @path log_update "%s: %s" % [@name, .any? ? "failed to retrieve features, trying fallback source" : "retrieving features"] raise "#{@source.basename}: no feature source defined" unless source source_path = Pathname(source).(@source.parent) .merge! args collection = case when ArcGIS::Service === source layer = ArcGIS::Service.new(source).layer(**.slice(:layer, :where), geometry: @map.neatline(**MARGIN).bbox, decode: true) layer.features(**.slice(:per_page)) do |count, total| log_update "%s: retrieved %i of %i feature%s" % [@name, count, total, (?s if total > 1)] end.reproject_to(@map.neatline.projection) when Shapefile::Source === source_path layer = Shapefile::Source.new(source_path).layer(**.slice(:where, :sql, :layer), geometry: @map.neatline(**MARGIN), projection: @map.neatline.projection) layer.features else raise "#{@source.basename}: invalid feature source: #{source}" end next collection, rescue ArcGIS::Connection::Error => error retry rescue StopIteration raise error end.each do |collection, | rotation_attribute, arithmetic = case [:rotation] when /^90 - (\w+)$/ then [$1, true] when String then [:rotation] end collection.map! do |feature| categories = [*[:category]].flat_map do |category| Hash === category ? [*category] : [category] end.map do |attribute, substitutions| value = feature.fetch(attribute, attribute) substitutions ? substitutions.fetch(value, value) : value end [:sizes].tap do |mm, max = 9| unit = (mm == true ? 5 : mm) case feature when GeoJSON::LineString, GeoJSON::MultiLineString size = (Math::log2(feature.length) - Math::log2(unit)).ceil rescue 0 categories << size.clamp(0, max) when GeoJSON::Polygon, GeoJSON::MultiPolygon size = (0.5 * Math::log2(feature.area) - Math::log2(unit)).ceil rescue 0 categories << size.clamp(0, max) end end if [:sizes] rotation = case feature when GeoJSON::Point, GeoJSON::MultiPoint value = begin Float feature.fetch(rotation_attribute) rescue KeyError, TypeError, ArgumentError 0.0 end categories << (value.zero? ? "unrotated" : "rotated") arithmetic ? 90 - value : value end if rotation_attribute labels = Array([:label]).map do |attribute| feature.fetch(attribute, attribute) end.map(&:to_s).reject(&:empty?) dual = [:dual].then do |attribute| feature.fetch(attribute, attribute) if attribute end categories = categories.map(&:to_s).reject(&:empty?).map(&method(:categorise)) properties = Hash[] properties["category"] = categories if categories.any? properties["label"] = labels if labels.any? properties["dual"] = dual if dual properties["draw"] = false if [:draw] == false properties["draw"] = false if @name =~ /[-_]labels$/ && !.key?(:draw) properties["rotation"] = rotation if rotation feature.with_properties(properties) end end.map(&:first).inject(&:merge).with_name(@name) end |