Skip to content

Commit

Permalink
Update GeoJSON APIs (#19927)
Browse files Browse the repository at this point in the history
API and implementation updates for GeoJSON
  • Loading branch information
alzimmermsft authored Mar 24, 2021
1 parent 200a1aa commit a4f9c7f
Show file tree
Hide file tree
Showing 21 changed files with 201 additions and 272 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@

package com.azure.core.experimental.geojson;

import com.azure.core.annotation.Immutable;
import com.azure.core.util.logging.ClientLogger;

import java.util.AbstractList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
Expand All @@ -21,7 +19,9 @@
*
* @param <T> The type of geometry coordinates.
*/
public class GeoArray<T> extends AbstractList<T> {
@Immutable
final class GeoArray<T> extends AbstractList<T> {
private static final String NO_MUTATION_MESSAGE = "GeoArray cannot be mutated.";
private final ClientLogger logger = new ClientLogger(GeoArray.class);

private final Object container;
Expand All @@ -37,8 +37,8 @@ public T get(int index) {
return (T) ((List<?>) container).get(index);
} else if (container instanceof GeoPointCollection) {
return (T) ((GeoPointCollection) container).getPoints().get(index).getCoordinates();
} else if (container instanceof GeoLineCollection) {
return (T) ((GeoLineCollection) container).getLines().get(index).getCoordinates();
} else if (container instanceof GeoLineStringCollection) {
return (T) ((GeoLineStringCollection) container).getLines().get(index).getCoordinates();
} else if (container instanceof GeoPolygon) {
return (T) ((GeoPolygon) container).getRings().get(index).getCoordinates();
} else if (container instanceof GeoPolygonCollection) {
Expand All @@ -54,8 +54,8 @@ public int size() {
return ((List<?>) container).size();
} else if (container instanceof GeoPointCollection) {
return ((GeoPointCollection) container).getPoints().size();
} else if (container instanceof GeoLineCollection) {
return ((GeoLineCollection) container).getLines().size();
} else if (container instanceof GeoLineStringCollection) {
return ((GeoLineStringCollection) container).getLines().size();
} else if (container instanceof GeoPolygon) {
return ((GeoPolygon) container).getRings().size();
} else if (container instanceof GeoPolygonCollection) {
Expand All @@ -65,88 +65,6 @@ public int size() {
}
}

@Override
public Iterator<T> iterator() {
return new GeoArrayIterator();
}

@Override
public ListIterator<T> listIterator(int index) {
return new GeoArrayListIterator(index);
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
* @param t The element that would be added.
* @return Throws an exception.
* @throws UnsupportedOperationException GeoArray doesn't support mutation.
*/
@Override
public boolean add(T t) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
* @param index The index where the element would be added.
* @param element The element that would be added.
* @throws UnsupportedOperationException GeoArray doesn't support mutation.
*/
@Override
public void add(int index, T element) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
* @param index The index where the element would be added.
* @param element The element that would be added.
* @return Throws an exception.
* @throws UnsupportedOperationException GeoArray doesn't support mutation.
*/
@Override
public T set(int index, T element) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
* @param index The index where the element would be removed.
* @return Throws an exception.
* @throws UnsupportedOperationException GeoArray doesn't support mutation.
*/
@Override
public T remove(int index) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
* @throws UnsupportedOperationException GeoArray doesn't support mutation.
*/
@Override
public void clear() {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
* @param index The index where the element would be added.
* @param c The collection of elements that would be added.
* @return Throws an exception.
* @throws UnsupportedOperationException GeoArray doesn't support mutation.
*/
@Override
public boolean addAll(int index, Collection<? extends T> c) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
Expand All @@ -156,19 +74,7 @@ public boolean addAll(int index, Collection<? extends T> c) {
*/
@Override
public boolean remove(Object o) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

/**
* Throws {@link UnsupportedOperationException} as GeoArray doesn't support mutation.
*
* @param c The collection of elements that would be added.
* @return Throws an exception.
* @throws UnsupportedOperationException GeoArray doesn't support mutation.
*/
@Override
public boolean addAll(Collection<? extends T> c) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
throw logger.logExceptionAsError(new UnsupportedOperationException(NO_MUTATION_MESSAGE));
}

/**
Expand All @@ -180,7 +86,7 @@ public boolean addAll(Collection<? extends T> c) {
*/
@Override
public boolean removeAll(Collection<?> c) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
throw logger.logExceptionAsError(new UnsupportedOperationException(NO_MUTATION_MESSAGE));
}

/**
Expand All @@ -192,7 +98,7 @@ public boolean removeAll(Collection<?> c) {
*/
@Override
public boolean retainAll(Collection<?> c) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
throw logger.logExceptionAsError(new UnsupportedOperationException(NO_MUTATION_MESSAGE));
}

/**
Expand All @@ -203,7 +109,7 @@ public boolean retainAll(Collection<?> c) {
*/
@Override
public void replaceAll(UnaryOperator<T> operator) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
throw logger.logExceptionAsError(new UnsupportedOperationException(NO_MUTATION_MESSAGE));
}

/**
Expand All @@ -214,7 +120,7 @@ public void replaceAll(UnaryOperator<T> operator) {
*/
@Override
public void sort(Comparator<? super T> c) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
throw logger.logExceptionAsError(new UnsupportedOperationException(NO_MUTATION_MESSAGE));
}

/**
Expand All @@ -226,7 +132,7 @@ public void sort(Comparator<? super T> c) {
*/
@Override
public boolean removeIf(Predicate<? super T> filter) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
throw logger.logExceptionAsError(new UnsupportedOperationException(NO_MUTATION_MESSAGE));
}

/**
Expand Down Expand Up @@ -260,75 +166,4 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hashCode(container);
}

private class GeoArrayIterator implements Iterator<T> {
transient int cursor;

@Override
public boolean hasNext() {
return cursor != size();
}

@Override
public T next() {
try {
int i = cursor;
T value = get(i);
cursor = i + 1;

return value;
} catch (IndexOutOfBoundsException ex) {
throw logger.logExceptionAsError(new NoSuchElementException());
}
}
}

private final class GeoArrayListIterator extends GeoArrayIterator implements ListIterator<T> {
private GeoArrayListIterator(int index) {
cursor = index;
}

@Override
public boolean hasPrevious() {
return cursor != 0;
}

@Override
public T previous() {
try {
int i = cursor - 1;
T value = get(i);
cursor = i;

return value;
} catch (IndexOutOfBoundsException ex) {
throw logger.logExceptionAsError(new NoSuchElementException());
}
}

@Override
public int nextIndex() {
return cursor;
}

@Override
public int previousIndex() {
return cursor - 1;
}

@Override
public void remove() {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

@Override
public void set(T t) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}

@Override
public void add(T t) {
throw logger.logExceptionAsError(new UnsupportedOperationException("GeoArray cannot be mutated."));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@

package com.azure.core.experimental.geojson;

import com.azure.core.annotation.Immutable;
import com.azure.core.util.logging.ClientLogger;

import java.util.Objects;

/**
* Represents a geometric bounding box.
*/
@Immutable
public final class GeoBoundingBox {
private final ClientLogger logger = new ClientLogger(GeoBoundingBox.class);

private final double west;
private final double south;
private final double east;
Expand All @@ -26,7 +32,7 @@ public final class GeoBoundingBox {
* @param north North latitudinal boundary.
*/
public GeoBoundingBox(double west, double south, double east, double north) {
this(west, south, east, north, null, null);
this(west, south, east, north, null, null, null);
}

/**
Expand All @@ -39,8 +45,16 @@ public GeoBoundingBox(double west, double south, double east, double north) {
* @param minAltitude Minimum altitude boundary.
* @param maxAltitude Maximum altitude boundary.
*/
public GeoBoundingBox(double west, double south, double east, double north, Double minAltitude,
Double maxAltitude) {
public GeoBoundingBox(double west, double south, double east, double north, double minAltitude,
double maxAltitude) {
this(west, south, east, north, minAltitude, maxAltitude, null);
}

/*
* This constructor allows the one above to require both min altitude and max altitude to be non-null.
*/
private GeoBoundingBox(double west, double south, double east, double north, Double minAltitude,
Double maxAltitude, String ignored) {
this.west = west;
this.south = south;
this.east = east;
Expand Down Expand Up @@ -119,11 +133,48 @@ public boolean equals(Object obj) {
}

GeoBoundingBox other = (GeoBoundingBox) obj;
return west == other.west
&& south == other.south
&& east == other.east
&& north == other.north
return Double.compare(west, other.west) == 0
&& Double.compare(south, other.south) == 0
&& Double.compare(east, other.east) == 0
&& Double.compare(north, other.north) == 0
&& Objects.equals(minAltitude, other.minAltitude)
&& Objects.equals(maxAltitude, other.maxAltitude);
}

/**
* Accesses the coordinates of the {@link GeoBoundingBox} as if it were in a JSON representation.
*
* @param i Index to access.
* @return The double value of the index.
* @throws IndexOutOfBoundsException If the {@link GeoBoundingBox} doesn't have altitude coordinates and {@code i}
* is greater than {@code 3} or {@link GeoBoundingBox} has altitude coordinates and {@code i} is greater than
*/
public double get(int i) {
if (minAltitude != null && maxAltitude != null) {
switch (i) {
case 0: return west;
case 1: return south;
case 2: return minAltitude;
case 3: return east;
case 4: return north;
case 5: return maxAltitude;
default: throw logger.logExceptionAsWarning(new IndexOutOfBoundsException("Index out of range: " + i));
}
} else {
switch (i) {
case 0: return west;
case 1: return south;
case 2: return east;
case 3: return north;
default: throw logger.logExceptionAsWarning(new IndexOutOfBoundsException("Index out of range: " + i));
}
}
}

@Override
public String toString() {
return (minAltitude != null && maxAltitude != null)
? String.format("[%s, %s, %s, %s, %s, %s]", west, south, minAltitude, east, north, maxAltitude)
: String.format("[%s, %s, %s, %s]", west, south, east, north);
}
}
Loading

0 comments on commit a4f9c7f

Please sign in to comment.