MaplyVectorObject
Objective-C
@interface MaplyVectorObject : NSObject
Swift
class MaplyVectorObject : NSObject
Maply Vector Object represents zero or more vector features.
The Vector Object can hold several vector features of the same or different types. It’s meant to be a fairly opaque structure, often read from GeoJSON or Shapefiles. It’s less opaque than originally planned, however, and sports a number of specific methods.
If you’re doing real vector manipulation, it’s best to do it somewhere else and then create one of these as needed for display.
Vector Objects can be created directly or read from a MaplyVectorDatabase. They are typically then displayed on top of a MaplyViewController or WhirlyGlobeViewController as vectors.
Vector Objects vertices are always in geographic, with longitude = x and latitude = y.
-
Turn this off to make this vector invisible to selection. On by default.
Declaration
Objective-C
@property (nonatomic) _Bool selectable;
Swift
var selectable: Bool { get set }
-
Return the attributes for the vector object.
All vectors should have some set of attribution. If there’s more than one vector feature here, we’ll return the attributes on the first one.
The attribution is returned as an NSDictionary and, though you can modify it, you probably shouldn’t.
Declaration
Objective-C
@property (nonatomic, readonly) NSMutableDictionary *_Nullable attributes;
Swift
var attributes: NSMutableDictionary? { get }
-
Parse vector data from geoJSON.
Returns one object to represent the whole thing, which might include multiple different vectors. This version uses the faster JSON parser.
We assume the geoJSON is all in decimal degrees in WGS84.
Declaration
Objective-C
+ (MaplyVectorObject *_Nullable)VectorObjectFromGeoJSON: (NSData *_Nonnull)geoJSON;
Swift
/*not inherited*/ init?(fromGeoJSON geoJSON: Data)
-
Parse vector data from geoJSON.
Returns one object to represent the whole thing, which might include multiple different vectors. This version uses slower JSON parser.
We assume the geoJSON is all in decimal degrees in WGS84.
Declaration
Objective-C
+ (MaplyVectorObject *_Nullable)VectorObjectFromGeoJSONApple: (NSData *_Nonnull)geoJSON;
Swift
/*not inherited*/ init?(fromGeoJSONApple geoJSON: Data)
-
Parse vector data from geoJSON.
Returns one object to represent the whole thing, which might include multiple different vectors. This version parses its data from an NSDictionary, which had to be parsed from JSON at some point. Probably the slower path.
We assume the geoJSON is all in decimal degrees in WGS84.
Declaration
Objective-C
+ (MaplyVectorObject *_Nullable)VectorObjectFromGeoJSONDictionary: (NSDictionary *_Nonnull)geoJSON;
Swift
/*not inherited*/ init?(fromGeoJSONDictionary geoJSON: [AnyHashable : Any])
-
Read vector objects from the given shapefile.
This will read all the shapes in the given shapefile into memory and return them as one MaplyVectorObject.
Declaration
Objective-C
+ (MaplyVectorObject *_Nullable)VectorObjectFromShapeFile: (NSString *_Nonnull)fileName;
Swift
/*not inherited*/ init?(fromShapeFile fileName: String)
Parameters
fileName
The basename of the shape file. Don’t include the extension.
Return Value
The vector object(s) read from the file or nil on failure.
-
Parse vector objects from a JSON assembly.
This version can deal with non-compliant assemblies returned by the experimental OSM server
Declaration
Objective-C
+ (NSDictionary *_Nullable)VectorObjectsFromGeoJSONAssembly: (NSData *_Nonnull)geoJSON;
Swift
class func vectorObjects(fromGeoJSONAssembly geoJSON: Data) -> [AnyHashable : Any]?
-
Initialize with a single data point and attribution.
This version takes a single coordinate and the attributes to go with it.
Declaration
Objective-C
- (nonnull instancetype)initWithPoint:(MaplyCoordinate)coord attributes:(NSDictionary *_Nullable)attr;
Swift
init(point coord: MaplyCoordinate, attributes attr: [AnyHashable : Any]? = nil)
-
Initialize with a single data point and attribution.
This version takes a single coordinate and the attributes to go with it.
Declaration
Objective-C
- (nonnull instancetype)initWithPointRef:(MaplyCoordinate *_Nonnull)coord attributes:(NSDictionary *_Nullable)attr;
Swift
init(pointRef coord: UnsafeMutablePointer<MaplyCoordinate>, attributes attr: [AnyHashable : Any]? = nil)
-
Initialize with a linear feature.
This version takes an array of coordinate pairs (as NSNumber) and the attribution. With this it will make a linear feature.
Declaration
Objective-C
- (nonnull instancetype)initWithLineString:(NSArray *_Nonnull)coords attributes:(NSDictionary *_Nullable)attr;
Swift
init(lineString coords: [Any], attributes attr: [AnyHashable : Any]? = nil)
-
Initialize with a linear feature.
This version takes an array of coordinates, the size of that array and the attribution. With this it will make a linear feature.
Declaration
Objective-C
- (nonnull instancetype)initWithLineString:(MaplyCoordinate *_Nonnull)coords numCoords:(int)numCoords attributes:(NSDictionary *_Nullable)attr;
Swift
init(lineString coords: UnsafeMutablePointer<MaplyCoordinate>, numCoords: Int32, attributes attr: [AnyHashable : Any]? = nil)
-
Inintialize as an areal feature.
This version takes an array of coordinates, the size of that array and the attribution. With this it will make a single area feature with one (exterior) loop. To add loops, call addHole:numCoords:
Declaration
Objective-C
- (nonnull instancetype)initWithAreal:(MaplyCoordinate *_Nonnull)coords numCoords:(int)numCoords attributes:(NSDictionary *_Nullable)attr;
Swift
init(areal coords: UnsafeMutablePointer<MaplyCoordinate>, numCoords: Int32, attributes attr: [AnyHashable : Any]? = nil)
-
Inintialize as an areal feature.
This version takes an array of coordinates (2 numbers per coordinate). With this it will make a single area feature with one (exterior) loop. To add loops, call addHole:numCoords:
Declaration
Objective-C
- (nonnull instancetype)initWithArealArray:(NSArray<NSNumber *> *_Nonnull)coords attributes:(NSDictionary *_Nullable)attr;
Swift
init(arealArray coords: [NSNumber], attributes attr: [AnyHashable : Any]? = nil)
-
Initializes with vectors parsed from geoJSON.
Returns one object to represent the whole thing, which might include multiple different vectors. This version uses the faster JSON parser.
We assume the geoJSON is all in decimal degrees in WGS84.
Declaration
Objective-C
- (nullable instancetype)initWithGeoJSON:(NSData *_Nonnull)geoJSON;
Swift
init?(geoJSON: Data)
-
Initializes with vector parsed from geoJSON.
Returns one object to represent the whole thing, which might include multiple different vectors. This version uses slower JSON parser.
We assume the geoJSON is all in decimal degrees in WGS84.
Declaration
Objective-C
- (nullable instancetype)initWithGeoJSONApple:(NSData *_Nonnull)geoJSON;
Swift
init?(geoJSONApple geoJSON: Data)
-
Initializes with vector parsed from geoJSON.
Returns one object to represent the whole thing, which might include multiple different vectors. This version parses its data from an NSDictionary, which had to be parsed from JSON at some point. Probably the slower path.
We assume the geoJSON is all in decimal degrees in WGS84.
Declaration
Objective-C
- (nullable instancetype)initWithGeoJSONDictionary: (NSDictionary *_Nonnull)geoJSON;
Swift
init?(geoJSONDictionary geoJSON: [AnyHashable : Any])
-
Initializes with vectors read from the given shapefile.
This will read all the shapes in the given shapefile into memory and return them as one MaplyVectorObject.
Declaration
Objective-C
- (nullable instancetype)initWithShapeFile:(NSString *_Nonnull)fileName;
Swift
init?(shapeFile fileName: String)
Parameters
fileName
The basename of the shape file. Don’t include the extension.
Return Value
The vector object(s) read from the file or nil on failure.
-
Make a deep copy of the vector object and return it.
This makes a complete copy of the vector object, with all features and nothing shared.
Had to rename this because Apple’s private method scanner is dumb.
Declaration
Objective-C
- (MaplyVectorObject *_Nonnull)deepCopy2;
Swift
func deepCopy2() -> MaplyVectorObject
-
Reproject from one coordinate system to another.
This reprojects every single point in the points, linears, and areals (and mesh) from the source coordinate system to the destionation.
Typically, you’ll want Plate Carree for display, the destSystem is probably that.
For various reasons (e.g. scale), this will probably not work right for you.
Declaration
Objective-C
- (void)reprojectFrom:(MaplyCoordinateSystem *_Nonnull)srcSystem to:(MaplyCoordinateSystem *_Nonnull)destSystem;
Swift
func reproject(from srcSystem: MaplyCoordinateSystem, to destSystem: MaplyCoordinateSystem)
Parameters
srcSystem
The source coordinate system. The data is already in this sytem.
destSystem
The destination coordinate system. The data will be in this system on return.
-
Dump the feature(s) out as text
This will write each feature out as text for debugging.
Declaration
Objective-C
- (NSString *_Nonnull)log;
Swift
func log() -> String
-
Add a hole to an existing feature.
This method is expecting to find exactly one areal feature. If it finds one, it will add the given hole as a loop on the end of the list of loops.
Declaration
Objective-C
- (void)addHole:(MaplyCoordinate *_Nonnull)coords numCoords:(int)numCoords;
Swift
func addHole(_ coords: UnsafeMutablePointer<MaplyCoordinate>, numCoords: Int32)
-
Returns the type of the vector feature. This method returns the type of the vector. Since vector objects can contain multiple types of vectors at once, this is somewhat complicated.
Type Description MaplyVectorNoneType There are no features in this object. MaplyVectorPointType There are only points (and multi-points) in the object. MaplyVectorLinearType There are only linear features in the object. MaplyVectorLinear3dType There are only linear features with Z values in the object. MaplyVectorArealType There are only areal features in the object. MaplyVectorMultiType There are multiple features of different types in the object. Declaration
Objective-C
- (MaplyVectorObjectType)vectorType;
Swift
func vectorType() -> MaplyVectorObjectType
-
Run a point in polygon test on all the areal features within the object.
We’ll run a point in polygon test on all the areal features within the vector object. If the point is within one of them, we return true, otherwise false.
Declaration
Objective-C
- (_Bool)pointInAreal:(MaplyCoordinate)coord;
Swift
func point(inAreal coord: MaplyCoordinate) -> Bool
-
Test if any linear feature is within distance of coord
Declaration
Objective-C
- (_Bool)pointNearLinear:(MaplyCoordinate)coord distance:(float)maxDistance inViewController:(MaplyBaseViewController *_Nonnull)vc;
Swift
func pointNearLinear(_ coord: MaplyCoordinate, distance maxDistance: Float, in vc: MaplyBaseViewController) -> Bool
-
Calculate the center of the entire set of vectors in this object.
-
Copy the vectors in the given vector object into this one.
Declaration
Objective-C
- (void)mergeVectorsFrom:(MaplyVectorObject *_Nonnull)otherVec;
Swift
func mergeVectors(from otherVec: MaplyVectorObject)
-
For a linear feature, calculate the mid oint and rotation at that point.
The vector object contains a number of half baked geometric queries, this being one of them.
This finds the middle (as measured by distance) of a linear feature and then calculations an angle corresponding to the line segment that middle sits in.
Why? Think label road placement.
Declaration
Objective-C
- (_Bool)linearMiddle:(MaplyCoordinate *_Nonnull)middle rot:(double *_Nonnull)rot;
Swift
func linearMiddle(_ middle: UnsafeMutablePointer<MaplyCoordinate>, rot: UnsafeMutablePointer<Double>) -> Bool
-
Undocumented
Declaration
Objective-C
- (bool)linearMiddle:(MaplyCoordinate *__nullable)middle rot:(double *__nullable)rot displayCoordSys:(MaplyCoordinateSystem *__nonnull)coordSys;
Swift
func linearMiddle(_ middle: UnsafeMutablePointer<MaplyCoordinate>?, rot: UnsafeMutablePointer<Double>?, displayCoordSys coordSys: MaplyCoordinateSystem) -> Bool
-
For a linear feature, calculate the mid point.
This is a convenience method to be called without pointers (Swift)
If you need both the mid point and the rotation, this method is less efficient than the method with pointers.
Declaration
Objective-C
- (MaplyCoordinate)linearMiddle:(MaplyCoordinateSystem *_Nonnull)coordSys;
Swift
func linearMiddle(_ coordSys: MaplyCoordinateSystem) -> MaplyCoordinate
Return Value
kMaplyNullCoordinate in case of error
-
For a linear feature, calculate the mid point and returns the rotation at that point.
This is a convenience method to be called without pointers (Swift)
If you need both the mid point and the rotation, this method is less efficient than the method with pointers.
Declaration
Objective-C
- (double)linearMiddleRotation:(MaplyCoordinateSystem *_Nonnull)coordSys;
Swift
func linearMiddleRotation(_ coordSys: MaplyCoordinateSystem) -> Double
Return Value
DBL_MIN in case of error
-
return the middle coordinate in a line feature
Declaration
Objective-C
- (MaplyCoordinate)middleCoordinate;
Swift
func middleCoordinate() -> MaplyCoordinate
Return Value
kMaplyNullCoordinate in case of error
-
return the middle coordinate in a line feature.
Declaration
Objective-C
- (_Bool)middleCoordinate:(MaplyCoordinate *_Nonnull)middle;
Swift
func middleCoordinate(_ middle: UnsafeMutablePointer<MaplyCoordinate>) -> Bool
-
Calculate the center and extents of the largest loop in an areal feature.
The vector object contains a number of half baked geometric queries, this being one of them.
If this vector contains at least one areal feature, we’ll determine which loop is the largest and return the center of that loop, as well as its bounding box.
Why? Think label placement on an areal feature.
Declaration
Objective-C
- (_Bool)largestLoopCenter:(MaplyCoordinate *_Nullable)center mbrLL:(MaplyCoordinate *_Nullable)ll mbrUR:(MaplyCoordinate *_Nullable)ur;
Swift
func largestLoopCenter(_ center: UnsafeMutablePointer<MaplyCoordinate>?, mbrLL ll: UnsafeMutablePointer<MaplyCoordinate>?, mbrUR ur: UnsafeMutablePointer<MaplyCoordinate>?) -> Bool
Return Value
Returns false if there was no loop (i.e. probably isn’t an areal)
-
Calculate the centroid of the largest loop in the areal feature.
The centroid is a better center for label placement than the middle of the largest loop as calculated by largestLoopCenter:mbrLL:mbrUR:
Return Value
Returns the centroid structure. If there was no loop (i.e. probably isn’t an areal), the result will be kMaplyNullCoordinate
-
Calculate the centroid of the largest loop in the areal feature.
The centroid is a better center for label placement than the middle of the largest loop as calculated by largestLoopCenter:mbrLL:mbrUR:
Declaration
Objective-C
- (_Bool)centroid:(MaplyCoordinate *_Nonnull)centroid;
Swift
func centroid(_ centroid: UnsafeMutablePointer<MaplyCoordinate>) -> Bool
Return Value
Returns false if there was no loop (probably wasn’t an areal).
-
Calculate the bounding box of all the features in this vector object.
Declaration
Objective-C
- (MaplyBoundingBox)boundingBox;
Swift
func boundingBox() -> MaplyBoundingBox
Return Value
kMaplyNullBoundingBox in case of error
-
Calculate the bounding box of all the features in this vector object.
Declaration
Objective-C
- (_Bool)boundingBoxLL:(MaplyCoordinate *_Nonnull)ll ur:(MaplyCoordinate *_Nonnull)ur;
Swift
func boundingBoxLL(_ ll: UnsafeMutablePointer<MaplyCoordinate>, ur: UnsafeMutablePointer<MaplyCoordinate>) -> Bool
-
Calculate the area of the outer loops.
This returns the area of the outer loops of any areal features in the VectorObject.
Declaration
Objective-C
- (double)areaOfOuterLoops;
Swift
func areaOfOuterLoops() -> Double
-
Convert any linear features into areal features.
Convert linear features to areal features by closing each one individually.
Declaration
Objective-C
- (MaplyVectorObject *_Nonnull)linearsToAreals;
Swift
func linearsToAreals() -> MaplyVectorObject
-
Convert any areal features into outlines.
Declaration
Objective-C
- (MaplyVectorObject *_Nonnull)arealsToLinears;
Swift
func arealsToLinears() -> MaplyVectorObject
-
Filter out edges created from clipping areal features on the server.
In some very specific cases (OSM water) we get polygons that are obviously clipped along internal boundaries. We can clear this up with some very, very specific logic.
Input must be closed areals and output is linears.
Declaration
Objective-C
- (MaplyVectorObject *_Nonnull)filterClippedEdges;
Swift
func filterClippedEdges() -> MaplyVectorObject
-
Convert a feature to an NSArray of NSArrays of CLLocation points.
This is intended for areal features. It will convert those coordinates to CLLocation values and return them. Obviously this is intended for things that need CLLocation values.
Declaration
Objective-C
- (NSArray *_Nullable)asCLLocationArrays;
Swift
func asCLLocationArrays() -> [Any]?
Return Value
Returns an NSArray of NSArray’s which then contain CLLocation points.
-
Return the data as an NSArray of NSNumbers.
If this is a linear, we’ll return the points as an NSArray of NSNumbers.
Declaration
Objective-C
- (NSArray *_Nullable)asNumbers;
Swift
func asNumbers() -> [Any]?
-
Split up ths feature into individual features and return an array of them.
A vector object can represent multiple features with no real rhyme or reason to it. This method will make one vector object per feature, allowing you to operate on those individually.
Declaration
Objective-C
- (NSArray<MaplyVectorObject *> *_Nonnull)splitVectors;
Swift
func splitVectors() -> [MaplyVectorObject]
Return Value
An NSArray of MaplyVectorObject.
-
Subdivide the edges in this feature to a given tolerance.
This will break up long edges in a vector until they lie flat on a globe to a given epsilon. The epislon is in display coordinates (radius = 1.0). This routine breaks this up along geographic boundaries.
Declaration
Objective-C
- (void)subdivideToGlobe:(float)epsilon;
Swift
func subdivide(toGlobe epsilon: Float)
-
Subdivide the edges in this feature to a given tolerance, using great circle math.
This will break up long edges in a vector until they lie flat on a globe to a given epsilon using a great circle route. The epsilon is in display coordinates (radius = 1.0).
Declaration
Objective-C
- (void)subdivideToGlobeGreatCircle:(float)epsilon;
Swift
func subdivide(toGlobeGreatCircle epsilon: Float)
-
Subdivide the edges in this feature to a given tolerance, using great circle math.
This version samples a great circle to display on a flat map.
Declaration
Objective-C
- (void)subdivideToFlatGreatCircle:(float)epsilon;
Swift
func subdivide(toFlatGreatCircle epsilon: Float)
-
Tesselate the areal geometry in this vector object and return triangles.
This will attempt to tesselate the areals (with holes) and turn them into triangles. No attribution will be assigned to the new triangles, so be aware. The tesselator is the GLU based one and does a decent job. Odds are if there’s something wrong it’s in the input data.
Declaration
Objective-C
- (MaplyVectorObject *_Nonnull)tesselate;
Swift
func tesselate() -> MaplyVectorObject
-
Clip the given (presumably areal) feature(s) to a grid in radians of the given size.
This will run through the loops in the input vectors and clip them against a grid. The grid size is given in radians.
Declaration
Objective-C
- (MaplyVectorObject *_Nullable)clipToGrid:(CGSize)gridSize;
Swift
func clip(toGrid gridSize: CGSize) -> MaplyVectorObject?
Return Value
New areal features broken up along the grid.
-
Clip the given (probably areal) features to the given bounding box.
This will run through the loops of the areal features and clip them against a bounding box.
The bounding box should be in the same coordinate system as the grid, probably radians.
Declaration
Objective-C
- (MaplyVectorObject *_Nullable)clipToMbr:(MaplyCoordinate)ll upperRight:(MaplyCoordinate)ur;
Swift
func clip(toMbr ll: MaplyCoordinate, upperRight ur: MaplyCoordinate) -> MaplyVectorObject?
Return Value
The new areal features will be clipped along the bounding box.