module GeoRuby#:nodoc: module SimpleFeatures # Default SRID DEFAULT_SRID = 4326 unless defined? DEFAULT_SRID #Root of all geometric data classes. #Objects of class Geometry should not be instantiated. class Geometry #SRID of the geometry attr_reader :srid #writer defined below #Flag indicating if the z ordinate of the geometry is meaningful attr_accessor :with_z alias :with_z? :with_z #Flag indicating if the m ordinate of the geometry is meaningful attr_accessor :with_m alias :with_m? :with_m def initialize(srid=DEFAULT_SRID, with_z=false, with_m=false) @srid=srid @with_z=with_z @with_m=with_m end def srid=(new_srid) @srid = new_srid unless self.is_a?(Point) self.each do |geom| geom.srid=new_srid end end end # to be implemented in subclasses def bounding_box end # to be implemented in subclasses def m_range end # # Returns an Envelope object for the geometry # def envelope Envelope.from_points(bounding_box, srid,with_z) end # # Outputs the geometry as an EWKB string. # # The +allow_srid+, +allow_z+ and +allow_m+ arguments allow the output # to include srid, z and m respectively if they are present in the geometry. # If these arguments are set to false, srid, z and m are not included, # even if they are present in the geometry. # By default, the output string contains all the information in the object. # def as_ewkb(allow_srid=true, allow_z=true, allow_m=true) ewkb = 1.chr #little_endian by default type = binary_geometry_type type = type | Z_MASK if @with_z and allow_z type = type | M_MASK if @with_m and allow_m if allow_srid type = type | SRID_MASK ewkb << [type, @srid].pack("VV") else ewkb << [type].pack("V") end ewkb << binary_representation(allow_z, allow_m) end # # Outputs the geometry as a strict WKB string. # def as_wkb as_ewkb(false, false, false) end # # Outputs the geometry as a HexEWKB string. # It is almost the same as a WKB string, except that each byte of a WKB # string is replaced by its hexadecimal 2-character representation in a HexEWKB string. # def as_hex_ewkb(allow_srid=true, allow_z=true, allow_m=true) as_ewkb(allow_srid, allow_z, allow_m).unpack('H*').join('').upcase end # # Outputs the geometry as a strict HexWKB string # def as_hex_wkb as_hex_ewkb(false,false,false) end # # Outputs the geometry as an EWKT string. # def as_ewkt(allow_srid=true,allow_z=true,allow_m=true) if allow_srid ewkt="SRID=#{@srid};" else ewkt="" end ewkt << text_geometry_type ewkt << "M" if @with_m and allow_m and (!@with_z or !allow_z) #to distinguish the M from the Z when there is actually no Z... ewkt << "(" << text_representation(allow_z,allow_m) << ")" end # # Outputs the geometry as strict WKT string. # def as_wkt as_ewkt(false, false, false) end # Outputs the geometry in georss format. # Assumes the geometries are in latlon format, with x as lon and y as lat. # Pass the :dialect option to swhit format. Possible values are: :simple (default), :w3cgeo and :gml. def as_georss(options = {}) dialect= options[:dialect] || :simple case(dialect) when :simple geom_attr = "" geom_attr += " featuretypetag=\"#{options[:featuretypetag]}\"" if options[:featuretypetag] geom_attr += " relationshiptag=\"#{options[:relationshiptag]}\"" if options[:relationshiptag] geom_attr += " floor=\"#{options[:floor]}\"" if options[:floor] geom_attr += " radius=\"#{options[:radius]}\"" if options[:radius] geom_attr += " elev=\"#{options[:elev]}\"" if options[:elev] georss_simple_representation(options.merge(:geom_attr => geom_attr)) when :w3cgeo georss_w3cgeo_representation(options) when :gml georss_gml_representation(options) end end # Iutputs the geometry in kml format : options are :id, :tesselate, :extrude, # :altitude_mode. If the altitude_mode option is not present, the Z (if present) will not be output (since # it won't be used by GE anyway: clampToGround is the default) def as_kml(options = {}) id_attr = "" id_attr = " id=\"#{options[:id]}\"" if options[:id] geom_data = "" geom_data += "#{options[:extrude]}\n" if options[:extrude] geom_data += "#{options[:tesselate]}\n" if options[:tesselate] geom_data += "#{options[:altitude_mode]}\n" if options[:altitude_mode] allow_z = (with_z || !options[:altitude].nil? )&& (!options[:altitude_mode].nil?) && options[:atitude_mode] != "clampToGround" fixed_z = options[:altitude] kml_representation(options.merge(:id_attr => id_attr, :geom_data => geom_data, :allow_z => allow_z, :fixed_z => fixed_z)) end # Creates a geometry based on a EWKB string. The actual class returned depends of the content of the string passed as argument. Since WKB strings are a subset of EWKB, they are also valid. def self.from_ewkb(ewkb) factory = GeometryFactory::new ewkb_parser = EWKBParser::new(factory) ewkb_parser.parse(ewkb) factory.geometry end # Creates a geometry based on a HexEWKB string given. def self.from_hex_ewkb(hexewkb) factory = GeometryFactory::new hexewkb_parser = HexEWKBParser::new(factory) hexewkb_parser.parse(hexewkb) factory.geometry end # Creates a geometry based on a EWKT string. Since WKT strings are a subset of EWKT, they are also valid. def self.from_ewkt(ewkt) factory = GeometryFactory::new ewkt_parser= EWKTParser::new(factory) ewkt_parser.parse(ewkt) factory.geometry end # Creates a geometry based on the GeoRSS string given. def self.from_georss(georss) georss_parser= GeorssParser::new georss_parser.parse(georss) georss_parser.geometry end # sends back an array: The first element is the goemetry based on the GeoRSS string passed as argument. The second one is the GeoRSSTags (found only with the Simple format) def self.from_georss_with_tags(georss) georss_parser= GeorssParser::new georss_parser.parse(georss,true) [georss_parser.geometry, georss_parser.georss_tags] end #Sends back a geometry from a KML encoded geometry string. def self.from_kml(kml) factory = GeometryFactory.new parser = KmlParser.new(factory) parser.parse(kml) end # Some GeoJSON files do not include srid info, so # we provide an optional parameter def self.from_geojson(geojson, srid=DEFAULT_SRID) geojson_parser= GeojsonParser::new geojson_parser.parse(geojson, srid) geojson_parser.geometry end private def self.split_coords(coords) coords.split(" ").collect { |coord| coord.gsub(","," ") } end end end end