src/models/polygon.ts
import { ILatLong } from '../interfaces/ilatlong';
import { IPolygonOptions } from '../interfaces/ipolygon-options';
/**
* Abstract class defining the contract for a polygon in the architecture specific implementation.
*
* @export
* @abstract
*/
export abstract class Polygon {
///
/// Field declarations
///
protected _centroid: ILatLong;
protected _center: ILatLong;
///
/// Property definitions
///
/**
* Gets the polygon's center.
* @readonly
* @memberof Polygon
*/
public get Center(): ILatLong {
if (this._center == null) {
this._center = this.GetBoundingCenter();
}
return this._center;
}
/**
* Gets the polygon's centroid.
* @readonly
* @memberof Polygon
*/
public get Centroid(): ILatLong {
if (this._centroid == null) {
this._centroid = this.GetPolygonCentroid();
}
return this._centroid;
}
/**
* Gets or sets the maximum zoom at which the label is displayed. Ignored or ShowLabel is false.
*
* @abstract
* @memberof Polygon
* @property
*/
public abstract get LabelMaxZoom(): number;
public abstract set LabelMaxZoom(val: number);
/**
* Gets or sets the minimum zoom at which the label is displayed. Ignored or ShowLabel is false.
*
* @abstract
* @memberof Polygon
* @property
*/
public abstract get LabelMinZoom(): number;
public abstract set LabelMinZoom(val: number);
/**
* Gets the polygon metadata.
*
* @readonly
* @abstract
* @memberof Polygon
*/
public abstract get Metadata(): Map<string, any>;
/**
* Gets the native primitve implementing the polygon.
*
* @readonly
* @memberof Polygon
*/
public abstract get NativePrimitve(): any;
/**
* Gets or sets whether to show the label
*
* @abstract
* @memberof Polygon
* @property
*/
public abstract get ShowLabel(): boolean;
public abstract set ShowLabel(val: boolean);
/**
* Gets or sets whether to show the tooltip
*
* @abstract
* @memberof Polygon
* @property
*/
public abstract get ShowTooltip(): boolean;
public abstract set ShowTooltip(val: boolean);
/**
* Gets or sets the title off the polygon
*
* @abstract
* @memberof Polygon
* @property
*/
public abstract get Title(): string;
public abstract set Title(val: string);
///
/// Public methods
///
/**
* Adds a delegate for an event.
*
* @abstract
* @param eventType - String containing the event name.
* @param fn - Delegate function to execute when the event occurs.
* @memberof Polygon
*/
public abstract AddListener(eventType: string, fn: Function): void;
/**
* Deleted the polygon.
*
* @abstract
*
* @memberof Polygon
*/
public abstract Delete(): void;
/**
* Gets whether the polygon is draggable.
*
* @abstract
* @returns - True if the polygon is dragable, false otherwise.
*
* @memberof Polygon
*/
public abstract GetDraggable(): boolean;
/**
* Gets whether the polygon path can be edited.
*
* @abstract
* @returns - True if the path can be edited, false otherwise.
*
* @memberof Polygon
*/
public abstract GetEditable(): boolean;
/**
* Gets the polygon path.
*
* @abstract
* @returns - Array of ILatLong objects describing the polygon path.
*
* @memberof Polygon
*/
public abstract GetPath(): Array<ILatLong>;
/**
* Gets the polygon paths.
*
* @abstract
* @returns - Array of Array of ILatLong objects describing multiple polygon paths.
*
* @memberof Polygon
*/
public abstract GetPaths(): Array<Array<ILatLong>>;
/**
* Gets whether the polygon is visible.
*
* @abstract
* @returns - True if the polygon is visible, false otherwise.
*
* @memberof Polygon
*/
public abstract GetVisible(): boolean;
/**
* Sets whether the polygon is dragable.
*
* @abstract
* @param draggable - True to make the polygon dragable, false otherwise.
*
* @memberof Polygon
*/
public abstract SetDraggable(draggable: boolean): void;
/**
* Sets wether the polygon path is editable.
*
* @abstract
* @param editable - True to make polygon path editable, false otherwise.
*
* @memberof Polygon
*/
public abstract SetEditable(editable: boolean): void;
/**
* Sets the polygon options
*
* @abstract
* @param options - {@link ILatLong} object containing the options. The options are merged with hte ones
* already on the underlying model.
*
* @memberof Polygon
*/
public abstract SetOptions(options: IPolygonOptions): void;
/**
* Sets the polygon path.
*
* @abstract
* @param path - An Array of {@link ILatLong} (or array of arrays) describing the polygons path.
*
* @memberof Polygon
*/
public abstract SetPath(path: Array<ILatLong> | Array<ILatLong>): void;
/**
* Set the polygon path or paths.
*
* @abstract
* @param paths An Array of {@link ILatLong}
* (or array of arrays) describing the polygons path(s).
*
* @memberof Polygon
*/
public abstract SetPaths(paths: Array<Array<ILatLong>> | Array<ILatLong>): void;
/**
* Sets whether the polygon is visible.
*
* @abstract
* @param visible - True to set the polygon visible, false otherwise.
*
* @memberof Polygon
*/
public abstract SetVisible(visible: boolean): void;
///
/// Protected methods
///
/**
* Gets the center of the polygons' bounding box.
*
* @returns - ILatLong object containing the center of the bounding box.
* @memberof Polygon
* @method
* @protected
*/
protected GetBoundingCenter(): ILatLong {
let c: ILatLong = {latitude: 0, longitude: 0};
let x1: number = 90, x2: number = -90, y1: number = 180, y2: number = -180;
const path: Array<Array<ILatLong>> = this.GetPaths();
if (path) {
path.forEach(inner => inner.forEach(p => {
if (p.latitude < x1) { x1 = p.latitude; }
if (p.latitude > x2) { x2 = p.latitude; }
if (p.longitude < y1) { y1 = p.longitude; }
if (p.longitude > y2) { y2 = p.longitude; }
}));
c.latitude = x1 + (x2 - x1) / 2;
c.longitude = y1 + (y2 - y1) / 2;
}
else {
c = null;
}
return c;
}
/**
* Get the centroid of the polygon based on the polygon path.
*
* @returns - The centroid coordinates of the polygon.
* @memberof Polygon
* @method
* @protected
*/
protected GetPolygonCentroid(): ILatLong {
let c: ILatLong = {latitude: 0, longitude: 0};
const path: Array<Array<ILatLong>> = this.GetPaths();
const off = path[0][0];
if (off != null) {
let twicearea: number = 0;
let x: number = 0;
let y: number = 0;
let p1: ILatLong, p2: ILatLong;
let f: number;
for (let k = 0; k < path.length; k++) {
for (let i = 0, j = path[k].length - 1; i < path[k].length; j = i++) {
p1 = path[k][i];
p2 = path[k][j];
f = (p1.latitude - off.latitude) * (p2.longitude - off.longitude) -
(p2.latitude - off.latitude) * (p1.longitude - off.longitude);
twicearea += f;
x += (p1.latitude + p2.latitude - 2 * off.latitude) * f;
y += (p1.longitude + p2.longitude - 2 * off.longitude) * f;
}
}
if (twicearea !== 0) {
f = twicearea * 3;
c.latitude = x / f + off.latitude;
c.longitude = y / f + off.longitude;
}
else {
c.latitude = off.latitude;
c.longitude = off.longitude;
}
}
else {
c = null;
}
return c;
}
}