All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.parse.ParsePolygon Maven / Gradle / Ivy

/*
 * Copyright (c) 2015-present, Parse, LLC.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */
package com.parse;

import android.location.Criteria;
import android.location.Location;
import android.os.Parcel;
import android.os.Parcelable;

import org.json.JSONArray;
import org.json.JSONException;

import java.util.Locale;
import java.util.List;

import bolts.Continuation;
import bolts.Task;

/**
 * {@code ParsePolygon} represents a set of coordinates that may be associated with a key
 * in a {@link ParseObject} or used as a reference point for geo queries. This allows proximity
 * based queries on the key.
 *
 * Example:
 * 
 * List points = new ArrayList();
 * points.add(new ParseGeoPoint(0,0));
 * points.add(new ParseGeoPoint(0,1));
 * points.add(new ParseGeoPoint(1,1));
 * points.add(new ParseGeoPoint(1,0));
 * ParsePolygon polygon = new ParsePolygon(points);
 * ParseObject object = new ParseObject("PlaceObject");
 * object.put("area", polygon);
 * object.save();
 * 
*/ public class ParsePolygon implements Parcelable { private List coordinates; /** * Creates a new polygon with the specified {@link ParseGeoPoint}. * * @param coords * The polygon's coordinates. */ public ParsePolygon(List coords) { setCoordinates(coords); } /** * Creates a copy of {@code polygon}; * * @param polygon * The polygon to copy. */ public ParsePolygon(ParsePolygon polygon) { this(polygon.getCoordinates()); } /** * Creates a new point instance from a {@link Parcel} source. This is used when unparceling a * ParsePolygon. Subclasses that need Parcelable behavior should provide their own * {@link android.os.Parcelable.Creator} and override this constructor. * * @param source The recovered parcel. */ protected ParsePolygon(Parcel source) { this(source, ParseParcelDecoder.get()); } /** * Creates a new point instance from a {@link Parcel} using the given {@link ParseParcelDecoder}. * The decoder is currently unused, but it might be in the future, plus this is the pattern we * are using in parcelable classes. * * @param source the parcel * @param decoder the decoder */ ParsePolygon(Parcel source, ParseParcelDecoder decoder) { setCoordinates(source.readArrayList(null)); } /** * Set coordinates. Valid are Array of GeoPoint, ParseGeoPoint or Location * at least 3 points * * @param coords * The polygon's coordinates. */ public void setCoordinates(List coords) { this.coordinates = ParsePolygon.validate(coords); } /** * Get coordinates. */ public List getCoordinates() { return coordinates; } /** * Get converts coordinate to JSONArray. */ protected JSONArray coordinatesToJSONArray() throws JSONException{ JSONArray points = new JSONArray(); for (ParseGeoPoint coordinate : coordinates) { JSONArray point = new JSONArray(); point.put(coordinate.getLatitude()); point.put(coordinate.getLongitude()); points.put(point); } return points; } /** * Checks if this {@code ParsePolygon}; contains {@link ParseGeoPoint}. */ public boolean containsPoint(ParseGeoPoint point) { double minX = coordinates.get(0).getLatitude(); double maxX = coordinates.get(0).getLatitude(); double minY = coordinates.get(0).getLongitude(); double maxY = coordinates.get(0).getLongitude(); for ( int i = 1; i < coordinates.size(); i += 1) { ParseGeoPoint geoPoint = coordinates.get(i); minX = Math.min(geoPoint.getLatitude(), minX); maxX = Math.max(geoPoint.getLatitude(), maxX); minY = Math.min(geoPoint.getLongitude(), minY); maxY = Math.max(geoPoint.getLongitude(), maxY); } boolean outside = point.getLatitude() < minX || point.getLatitude() > maxX || point.getLongitude() < minY || point.getLongitude() > maxY; if (outside) { return false; } boolean inside = false; for (int i = 0, j = coordinates.size() - 1 ; i < coordinates.size(); j = i++) { double startX = coordinates.get(i).getLatitude(); double startY = coordinates.get(i).getLongitude(); double endX = coordinates.get(j).getLatitude(); double endY = coordinates.get(j).getLongitude(); boolean intersect = (( startY > point.getLongitude() ) != ( endY > point.getLongitude() ) && point.getLatitude() < ( endX - startX ) * ( point.getLongitude() - startY ) / ( endY - startY ) + startX); if (intersect) { inside = !inside; } } return inside; } /** * Throws exception for invalid coordinates. */ static List validate(List coords) { if (coords.size() < 3) { throw new IllegalArgumentException("Polygon must have at least 3 GeoPoints"); } return coords; } @Override public boolean equals(Object obj) { if (obj == null || !(obj instanceof ParsePolygon)) { return false; } if (obj == this) { return true; } ParsePolygon other = (ParsePolygon) obj; if (coordinates.size() != other.getCoordinates().size()) { return false; } boolean isEqual = true; for (int i = 0; i < coordinates.size(); i += 1) { if (coordinates.get(i).getLatitude() != other.getCoordinates().get(i).getLatitude() || coordinates.get(i).getLongitude() != other.getCoordinates().get(i).getLongitude()) { isEqual = false; break; } } return isEqual; } @Override public String toString() { return String.format(Locale.US, "ParsePolygon: %s", coordinates); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { writeToParcel(dest, ParseParcelEncoder.get()); } void writeToParcel(Parcel dest, ParseParcelEncoder encoder) { dest.writeList(coordinates); } public final static Creator CREATOR = new Creator() { @Override public ParsePolygon createFromParcel(Parcel source) { return new ParsePolygon(source, ParseParcelDecoder.get()); } @Override public ParsePolygon[] newArray(int size) { return new ParsePolygon[size]; } }; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy