Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
Rugged
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Orekit
Rugged
Commits
a45d3361
Commit
a45d3361
authored
10 years ago
by
Luc Maisonobe
Browse files
Options
Downloads
Patches
Plain Diff
Simplified tiles cache.
parent
a2dd4d53
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/main/java/org/orekit/rugged/raster/TilesCache.java
+29
-295
29 additions, 295 deletions
src/main/java/org/orekit/rugged/raster/TilesCache.java
src/test/java/org/orekit/rugged/raster/TilesCacheTest.java
+7
-0
7 additions, 0 deletions
src/test/java/org/orekit/rugged/raster/TilesCacheTest.java
with
36 additions
and
295 deletions
src/main/java/org/orekit/rugged/raster/TilesCache.java
+
29
−
295
View file @
a45d3361
...
...
@@ -16,18 +16,11 @@
*/
package
org.orekit.rugged.raster
;
import
java.io.Serializable
;
import
java.lang.reflect.Array
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.apache.commons.math3.util.FastMath
;
import
org.orekit.rugged.errors.RuggedException
;
import
org.orekit.rugged.errors.RuggedMessages
;
import
org.orekit.rugged.raster.Tile.Location
;
/** Cache for Digital Elevation Model {@link Tile tiles}.
* <p>
...
...
@@ -44,14 +37,8 @@ public class TilesCache<T extends Tile> {
/** Updater for retrieving tiles data. */
private
final
TileUpdater
updater
;
/** Search optimized cache. */
private
List
<
TilesStrip
>
searchCache
;
/** Eviction queue. */
private
T
[]
evictionQueue
;
/** Index for next tile. */
private
int
next
;
/** Cache. */
private
final
T
[]
tiles
;
/** Simple constructor.
* @param factory factory for creating empty tiles
...
...
@@ -60,12 +47,10 @@ public class TilesCache<T extends Tile> {
*/
public
TilesCache
(
final
TileFactory
<
T
>
factory
,
final
TileUpdater
updater
,
final
int
maxTiles
)
{
this
.
factory
=
factory
;
this
.
updater
=
updater
;
this
.
searchCache
=
new
ArrayList
<
TilesStrip
>();
this
.
updater
=
updater
;
@SuppressWarnings
(
"unchecked"
)
final
T
[]
array
=
(
T
[])
Array
.
newInstance
(
Tile
.
class
,
maxTiles
+
1
);
this
.
evictionQueue
=
array
;
this
.
next
=
0
;
final
T
[]
array
=
(
T
[])
Array
.
newInstance
(
Tile
.
class
,
maxTiles
);
this
.
tiles
=
array
;
}
/** Get the tile covering a ground point.
...
...
@@ -76,296 +61,45 @@ public class TilesCache<T extends Tile> {
*/
public
T
getTile
(
final
double
latitude
,
final
double
longitude
)
throws
RuggedException
{
final
T
tile
=
getStrip
(
latitude
,
longitude
).
getTile
(
latitude
,
longitude
);
if
(
tile
.
getLocation
(
latitude
,
longitude
)
!=
Tile
.
Location
.
HAS_INTERPOLATION_NEIGHBORS
)
{
// this should happen only if user set up an inconsistent TileUpdater
throw
new
RuggedException
(
RuggedMessages
.
TILE_WITHOUT_REQUIRED_NEIGHBORS_SELECTED
,
FastMath
.
toDegrees
(
latitude
),
FastMath
.
toDegrees
(
longitude
));
}
return
tile
;
}
/** Create a tile covering a ground point.
* @param latitude latitude of the point
* @param longitude longitude of the point
* @return new tile covering the point
* @exception RuggedException if tile cannot be updated
*/
private
T
createTile
(
final
double
latitude
,
final
double
longitude
)
throws
RuggedException
{
// create the tile and retrieve its data
final
T
tile
=
factory
.
createTile
();
updater
.
updateTile
(
latitude
,
longitude
,
tile
);
tile
.
tileUpdateCompleted
();
return
tile
;
}
/** Append newly created tile at the end of the eviction queue.
* @param tile tile to append to queue
*/
private
void
appendToEvictionQueue
(
final
T
tile
)
{
evictionQueue
[
next
]
=
tile
;
next
=
(
next
+
1
)
%
evictionQueue
.
length
;
if
(
evictionQueue
[
next
]
!=
null
)
{
// the cache is full, we need to evict one tile
// from both the eviction cache and the search cache
for
(
final
Iterator
<
TilesStrip
>
iterator
=
searchCache
.
iterator
();
iterator
.
hasNext
();)
{
if
(
iterator
.
next
().
removeTile
(
evictionQueue
[
next
]))
{
evictionQueue
[
next
]
=
null
;
return
;
}
}
}
}
/** Get a strip covering a ground point.
* @param latitude ground point latitude
* @param longitude ground point longitude
* @return strip covering the ground point
* @exception RuggedException if tile cannot be updated
*/
private
TilesStrip
getStrip
(
final
double
latitude
,
final
double
longitude
)
throws
RuggedException
{
// look for a strip at the specified latitude
final
int
index
=
Collections
.
binarySearch
(
searchCache
,
new
BasicLatitudeProvider
(
latitude
),
new
LatitudeComparator
());
if
(
index
>=
0
)
{
// rare case, the latitude is an exact maximum latitude for a strip
return
searchCache
.
get
(
index
);
}
else
{
final
int
insertionPoint
=
-(
index
+
1
);
for
(
int
i
=
0
;
i
<
tiles
.
length
;
++
i
)
{
final
T
tile
=
tiles
[
i
];
if
(
tile
!=
null
&&
tile
.
getLocation
(
latitude
,
longitude
)
==
Tile
.
Location
.
HAS_INTERPOLATION_NEIGHBORS
)
{
// we have found the tile in the cache
if
(
insertionPoint
<
searchCache
.
size
())
{
final
TilesStrip
strip
=
searchCache
.
get
(
insertionPoint
);
if
(
strip
.
covers
(
latitude
))
{
// we have found an existing strip
return
strip
;
// put it on the front as it becomes the most recently used
while
(
i
>
0
)
{
tiles
[
i
]
=
tiles
[
i
-
1
];
--
i
;
}
}
// no existing strip covers the specified latitude, we need to create a new one
final
T
tile
=
createTile
(
latitude
,
longitude
);
final
TilesStrip
strip
=
new
TilesStrip
(
tile
);
searchCache
.
add
(
insertionPoint
,
strip
);
appendToEvictionQueue
(
tile
);
return
strip
;
}
}
/** Interface for retrieving latitude. */
private
interface
LatitudeProvider
{
/** Get latitude.
* @return latitude
*/
double
getLatitude
();
}
/** Basic implementation of {@link LatitudeProvider}. */
private
static
class
BasicLatitudeProvider
implements
LatitudeProvider
{
/** Latitude. */
private
final
double
latitude
;
/** Simple constructor.
* @param latitude latitude
*/
public
BasicLatitudeProvider
(
final
double
latitude
)
{
this
.
latitude
=
latitude
;
}
/** {@inheritDoc} */
@Override
public
double
getLatitude
()
{
return
latitude
;
}
}
/** Interface for retrieving longitude. */
private
interface
LongitudeProvider
{
tiles
[
0
]
=
tile
;
/** Get longitude.
* @return longitude
*/
double
getLongitude
();
}
/** Basic implementation of {@link LongitudeProvider}. */
private
static
class
BasicLongitudeProvider
implements
LongitudeProvider
{
/** Longitude. */
private
final
double
longitude
;
/** Simple constructor.
* @param longitude longitude
*/
public
BasicLongitudeProvider
(
final
double
longitude
)
{
this
.
longitude
=
longitude
;
}
/** {@inheritDoc} */
@Override
public
double
getLongitude
()
{
return
longitude
;
}
}
/** Strip of tiles for a given latitude. */
private
class
TilesStrip
implements
LatitudeProvider
{
/** Minimum latitude. */
private
final
double
minLatitude
;
/** Maximum latitude. */
private
final
double
maxLatitude
;
/** Tiles list. */
private
final
List
<
TileDecorator
>
tiles
;
/** Simple constructor.
* @param tile first tile to insert in the strip
*/
public
TilesStrip
(
final
T
tile
)
{
minLatitude
=
tile
.
getMinimumLatitude
();
maxLatitude
=
tile
.
getMaximumLatitude
();
tiles
=
new
ArrayList
<
TileDecorator
>();
tiles
.
add
(
new
TileDecorator
(
tile
));
}
/** Check if the strip covers a specified latitude.
* @param latitude latitude to check
* @return true if the strip covers the latitude
*/
public
boolean
covers
(
final
double
latitude
)
{
return
(
minLatitude
<=
latitude
)
&&
(
maxLatitude
>=
latitude
);
}
/** {@inheritDoc} */
@Override
public
double
getLatitude
()
{
return
maxLatitude
;
}
/** Get a tile covering a ground point.
* @param latitude ground point latitude
* @param longitude ground point longitude
* @return strip covering the ground point
* @exception RuggedException if tile cannot be updated
*/
public
T
getTile
(
final
double
latitude
,
final
double
longitude
)
throws
RuggedException
{
// look for a tile at the specified longitude
final
int
index
=
Collections
.
binarySearch
(
tiles
,
new
BasicLongitudeProvider
(
longitude
),
new
LongitudeComparator
());
if
(
index
>=
0
)
{
// rare case, the longitude is an exact maximum longitude for a tile
return
tiles
.
get
(
index
).
getTile
();
}
else
{
final
int
insertionPoint
=
-(
index
+
1
);
if
(
insertionPoint
<
tiles
.
size
())
{
final
T
tile
=
tiles
.
get
(
insertionPoint
).
getTile
();
if
(
tile
.
getLocation
(
latitude
,
longitude
)
==
Location
.
HAS_INTERPOLATION_NEIGHBORS
)
{
// we have found an existing tile
return
tile
;
}
}
// no existing tile covers the specified ground point, we need to create a new one
final
T
tile
=
createTile
(
latitude
,
longitude
);
tiles
.
add
(
insertionPoint
,
new
TileDecorator
(
tile
));
appendToEvictionQueue
(
tile
);
return
tile
;
}
}
/** Remove a tile from the strip.
* @param tile tile to remove
* @return true if the tile has been removed
*/
public
boolean
removeTile
(
final
Tile
tile
)
{
for
(
final
Iterator
<
TileDecorator
>
iterator
=
tiles
.
iterator
();
iterator
.
hasNext
();)
{
if
(
iterator
.
next
().
getTile
()
==
tile
)
{
iterator
.
remove
();
return
true
;
}
}
return
false
;
}
}
/** Decorator for tiles, implementing {@link LongitudeProvider}. */
private
class
TileDecorator
implements
LongitudeProvider
{
/** Underlying tile. */
private
final
T
tile
;
/** Simple constructor.
* @param tile tile to decorate
*/
public
TileDecorator
(
final
T
tile
)
{
this
.
tile
=
tile
;
}
/** Get the underlying tile.
* @return underlying tile
*/
public
T
getTile
()
{
return
tile
;
}
// none of the tiles in the cache covers the specified points
/** {@inheritDoc} */
@Override
public
double
getLongitude
()
{
return
tile
.
getMaximumLongitude
();
// make some room in the cache, possibly evicting the least recently used one
for
(
int
i
=
tiles
.
length
-
1
;
i
>
0
;
--
i
)
{
tiles
[
i
]
=
tiles
[
i
-
1
];
}
}
/** Comparator for sorting with respect to latitude. */
private
static
class
LatitudeComparator
implements
Comparator
<
LatitudeProvider
>,
Serializable
{
/** Serializable UID. */
private
static
final
long
serialVersionUID
=
20141212L
;
// create the tile and retrieve its data
final
T
tile
=
factory
.
createTile
();
updater
.
updateTile
(
latitude
,
longitude
,
tile
);
tile
.
tileUpdateCompleted
();
/** {@inheritDoc} */
@Override
public
int
compare
(
final
LatitudeProvider
o1
,
final
LatitudeProvider
o2
)
{
return
Double
.
compare
(
o1
.
getLatitude
(),
o2
.
getLatitude
());
if
(
tile
.
getLocation
(
latitude
,
longitude
)
!=
Tile
.
Location
.
HAS_INTERPOLATION_NEIGHBORS
)
{
// this should happen only if user set up an inconsistent TileUpdater
throw
new
RuggedException
(
RuggedMessages
.
TILE_WITHOUT_REQUIRED_NEIGHBORS_SELECTED
,
FastMath
.
toDegrees
(
latitude
),
FastMath
.
toDegrees
(
longitude
));
}
}
/** Comparator for sorting with respect to longitude. */
private
static
class
LongitudeComparator
implements
Comparator
<
LongitudeProvider
>,
Serializable
{
/** Serializable UID. */
private
static
final
long
serialVersionUID
=
20141212L
;
/** {@inheritDoc} */
@Override
public
int
compare
(
final
LongitudeProvider
o1
,
final
LongitudeProvider
o2
)
{
return
Double
.
compare
(
o1
.
getLongitude
(),
o2
.
getLongitude
());
}
tiles
[
0
]
=
tile
;
return
tile
;
}
...
...
This diff is collapsed.
Click to expand it.
src/test/java/org/orekit/rugged/raster/TilesCacheTest.java
+
7
−
0
View file @
a45d3361
...
...
@@ -65,6 +65,13 @@ public class TilesCacheTest {
}
Assert
.
assertEquals
(
12
,
factory
.
getCount
());
// ensure the (0.0, 0.0) tile is the least recently used one
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
for
(
int
j
=
0
;
j
<
3
;
++
j
)
{
cache
.
getTile
(
FastMath
.
toRadians
(
0.5
+
j
),
FastMath
.
toRadians
(
0.5
+
i
));
}
}
// ask for one point outside of the covered area, to evict the (0.0, 0.0) tile
cache
.
getTile
(
FastMath
.
toRadians
(
20.5
),
FastMath
.
toRadians
(
30.5
));
Assert
.
assertEquals
(
13
,
factory
.
getCount
());
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment