Skip to content
GitLab
Explore
Sign in
Register
Commits on Source (5)
New upstream version 2.10+dfsg
· 9b3489cc
Bas Couwenberg
authored
May 31, 2019
9b3489cc
Merge tag 'upstream/2.10+dfsg'
· 7cc2a61d
Bas Couwenberg
authored
May 31, 2019
Upstream version 2.10+dfsg
7cc2a61d
New upstream release.
· a3240f31
Bas Couwenberg
authored
May 31, 2019
a3240f31
Update copyright years for Vincent Privat.
· 037369a1
Bas Couwenberg
authored
May 31, 2019
037369a1
Set distribution to experimental.
· f308efc8
Bas Couwenberg
authored
May 31, 2019
f308efc8
Show whitespace changes
Inline
Side-by-side
Readme.txt
View file @
f308efc8
...
...
@@ -10,7 +10,7 @@ JMapViewer
(c) 2010-2011, Michael Vigovsky
(c) 2011-2017, Paul Hartmann
(c) 2011-2016, Gleb Smirnoff
(c) 2011-201
8
, Vincent Privat
(c) 2011-201
9
, Vincent Privat
(c) 2011, Jason Huntley
(c) 2012-2016, Simon Legner
(c) 2012, Teemu Koskinen
...
...
debian/changelog
View file @
f308efc8
jmapviewer (2.
9
+dfsg-
2) UNRELEASED
; urgency=medium
jmapviewer (2.
10
+dfsg-
1~exp1) experimental
; urgency=medium
* New upstream release.
* Remove package name from lintian overrides.
* Update copyright years for Vincent Privat.
-- Bas Couwenberg <sebastic@debian.org> Fri, 1
5
Ma
r
2019
15:56:05
+0
1
00
-- Bas Couwenberg <sebastic@debian.org> Fri,
3
1 Ma
y
2019
06:02:30
+0
2
00
jmapviewer (2.9+dfsg-1) unstable; urgency=medium
...
...
debian/copyright
View file @
f308efc8
...
...
@@ -25,7 +25,7 @@ Copyright: 2007, Tim Haussmann
2011-2017, Paul Hartmann
2017, Robert Scott
2009-2018, Dirk Stöcker
2011-201
8
, Vincent Privat
2011-201
9
, Vincent Privat
License: GPL-2+
Files: src/org/openstreetmap/gui/jmapviewer/tilesources/ScanexTileSource.java
...
...
src/org/openstreetmap/gui/jmapviewer/FeatureAdapter.java
View file @
f308efc8
...
...
@@ -8,17 +8,24 @@ import java.net.URI;
import
java.net.URISyntaxException
;
import
java.net.URL
;
import
java.text.MessageFormat
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.TreeMap
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
javax.imageio.ImageIO
;
/**
* Feature adapter allows to override JMapViewer behaviours from a client application such as JOSM.
*/
public
final
class
FeatureAdapter
{
private
static
BrowserAdapter
browserAdapter
=
new
DefaultBrowserAdapter
();
private
static
ImageAdapter
imageAdapter
=
new
DefaultImageAdapter
();
private
static
TranslationAdapter
translationAdapter
=
new
DefaultTranslationAdapter
();
private
static
LoggingAdapter
loggingAdapter
=
new
DefaultLoggingAdapter
();
private
static
SettingsAdapter
settingsAdapter
=
new
DefaultSettingsAdapter
();
private
FeatureAdapter
()
{
// private constructor for utility classes
...
...
@@ -41,6 +48,28 @@ public final class FeatureAdapter {
BufferedImage
read
(
URL
input
,
boolean
readMetadata
,
boolean
enforceTransparency
)
throws
IOException
;
}
/**
* Basic settings system allowing to store/retrieve String key/value pairs.
*/
public
interface
SettingsAdapter
{
/**
* Get settings value for a certain key and provide a default value.
* @param key the identifier for the setting
* @param def the default value. For each call of get() with a given key, the
* default value must be the same. {@code def} may be null.
* @return the corresponding value if the property has been set before, {@code def} otherwise
*/
String
get
(
String
key
,
String
def
);
/**
* Set a value for a certain setting.
* @param key the unique identifier for the setting
* @param value the value of the setting. Can be null or "" which both removes the key-value entry.
* @return {@code true}, if something has changed (i.e. value is different than before)
*/
boolean
put
(
String
key
,
String
value
);
}
public
static
void
registerBrowserAdapter
(
BrowserAdapter
browserAdapter
)
{
FeatureAdapter
.
browserAdapter
=
Objects
.
requireNonNull
(
browserAdapter
);
}
...
...
@@ -57,6 +86,15 @@ public final class FeatureAdapter {
FeatureAdapter
.
loggingAdapter
=
Objects
.
requireNonNull
(
loggingAdapter
);
}
/**
* Registers settings adapter.
* @param settingsAdapter settings adapter, must not be null
* @throws NullPointerException if settingsAdapter is null
*/
public
static
void
registerSettingsAdapter
(
SettingsAdapter
settingsAdapter
)
{
FeatureAdapter
.
settingsAdapter
=
Objects
.
requireNonNull
(
settingsAdapter
);
}
public
static
void
openLink
(
String
url
)
{
browserAdapter
.
openLink
(
url
);
}
...
...
@@ -73,6 +111,42 @@ public final class FeatureAdapter {
return
loggingAdapter
.
getLogger
(
name
);
}
public
static
Logger
getLogger
(
Class
<?>
klass
)
{
return
loggingAdapter
.
getLogger
(
klass
.
getSimpleName
());
}
/**
* Get settings value for a certain key and provide a default value.
* @param key the identifier for the setting
* @param def the default value. For each call of get() with a given key, the
* default value must be the same. {@code def} may be null.
* @return the corresponding value if the property has been set before, {@code def} otherwise
*/
public
static
String
getSetting
(
String
key
,
String
def
)
{
return
settingsAdapter
.
get
(
key
,
def
);
}
/**
* Get settings value for a certain key and provide a default value.
* @param key the identifier for the setting
* @param def the default value. For each call of get() with a given key, the
* default value must be the same. {@code def} may be null.
* @return the corresponding value if the property has been set before, {@code def} otherwise
*/
public
static
int
getIntSetting
(
String
key
,
int
def
)
{
return
Integer
.
parseInt
(
settingsAdapter
.
get
(
key
,
Integer
.
toString
(
def
)));
}
/**
* Set a value for a certain setting.
* @param key the unique identifier for the setting
* @param value the value of the setting. Can be null or "" which both removes the key-value entry.
* @return {@code true}, if something has changed (i.e. value is different than before)
*/
public
static
boolean
putSetting
(
String
key
,
String
value
)
{
return
settingsAdapter
.
put
(
key
,
value
);
}
public
static
class
DefaultBrowserAdapter
implements
BrowserAdapter
{
@Override
public
void
openLink
(
String
url
)
{
...
...
@@ -85,7 +159,7 @@ public final class FeatureAdapter {
e
.
printStackTrace
();
}
}
else
{
System
.
err
.
println
(
tr
(
"Opening link not supported on current platform (''{0}'')"
,
url
));
getLogger
(
FeatureAdapter
.
class
).
log
(
Level
.
SEVERE
,
tr
(
"Opening link not supported on current platform (''{0}'')"
,
url
));
}
}
}
...
...
@@ -110,4 +184,21 @@ public final class FeatureAdapter {
return
Logger
.
getLogger
(
name
);
}
}
/**
* Default settings adapter keeping settings in memory only.
*/
public
static
class
DefaultSettingsAdapter
implements
SettingsAdapter
{
private
final
Map
<
String
,
String
>
settings
=
new
TreeMap
<>();
@Override
public
String
get
(
String
key
,
String
def
)
{
return
settings
.
getOrDefault
(
key
,
def
);
}
@Override
public
boolean
put
(
String
key
,
String
value
)
{
return
!
Objects
.
equals
(
value
==
null
||
value
.
isEmpty
()
?
settings
.
remove
(
key
)
:
settings
.
put
(
key
,
value
),
value
);
}
}
}
src/org/openstreetmap/gui/jmapviewer/OsmTileLoader.java
View file @
f308efc8
...
...
@@ -13,6 +13,8 @@ import java.util.Map;
import
java.util.Map.Entry
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
org.openstreetmap.gui.jmapviewer.interfaces.TileJob
;
import
org.openstreetmap.gui.jmapviewer.interfaces.TileLoader
;
...
...
@@ -24,7 +26,22 @@ import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
* @author Jan Peter Stotz
*/
public
class
OsmTileLoader
implements
TileLoader
{
private
static
final
ThreadPoolExecutor
jobDispatcher
=
(
ThreadPoolExecutor
)
Executors
.
newFixedThreadPool
(
8
);
private
static
final
Logger
LOG
=
FeatureAdapter
.
getLogger
(
OsmTileLoader
.
class
);
/** Setting key for number of threads */
public
static
final
String
THREADS_SETTING
=
"jmapviewer.osm-tile-loader.threads"
;
private
static
final
int
DEFAULT_THREADS_NUMBER
=
8
;
private
static
int
nThreads
=
DEFAULT_THREADS_NUMBER
;
static
{
try
{
nThreads
=
FeatureAdapter
.
getIntSetting
(
THREADS_SETTING
,
DEFAULT_THREADS_NUMBER
);
}
catch
(
Exception
e
)
{
LOG
.
log
(
Level
.
SEVERE
,
e
.
getMessage
(),
e
);
}
}
private
static
final
ThreadPoolExecutor
jobDispatcher
=
(
ThreadPoolExecutor
)
Executors
.
newFixedThreadPool
(
nThreads
);
private
final
class
OsmTileJob
implements
TileJob
{
private
final
Tile
tile
;
...
...
@@ -68,10 +85,10 @@ public class OsmTileLoader implements TileLoader {
listener
.
tileLoadingFinished
(
tile
,
false
);
if
(
input
==
null
)
{
try
{
System
.
err
.
println
(
"Failed loading "
+
tile
.
getUrl
()
+
": "
LOG
.
log
(
Level
.
SEVERE
,
"Failed loading "
+
tile
.
getUrl
()
+
": "
+
e
.
getClass
()
+
": "
+
e
.
getMessage
());
}
catch
(
IOException
ioe
)
{
ioe
.
printStackTrace
(
);
LOG
.
log
(
Level
.
SEVERE
,
ioe
.
getMessage
(),
ioe
);
}
}
}
finally
{
...
...
@@ -102,12 +119,17 @@ public class OsmTileLoader implements TileLoader {
protected
TileLoaderListener
listener
;
/**
* Constructs a new {@code OsmTileLoader}.
* @param listener tile loader listener
*/
public
OsmTileLoader
(
TileLoaderListener
listener
)
{
this
(
listener
,
null
);
}
public
OsmTileLoader
(
TileLoaderListener
listener
,
Map
<
String
,
String
>
headers
)
{
this
.
headers
.
put
(
"Accept"
,
"text/html, image/png, image/jpeg, image/gif, */*"
);
this
.
headers
.
put
(
"User-Agent"
,
"JMapViewer Java/"
+
System
.
getProperty
(
"java.version"
));
if
(
headers
!=
null
)
{
this
.
headers
.
putAll
(
headers
);
}
...
...
src/org/openstreetmap/gui/jmapviewer/tilesources/BingAerialTileSource.java
View file @
f308efc8
...
...
@@ -14,6 +14,8 @@ import java.util.concurrent.Future;
import
java.util.concurrent.FutureTask
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeoutException
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
java.util.regex.Pattern
;
import
javax.xml.parsers.DocumentBuilder
;
...
...
@@ -42,7 +44,21 @@ import org.xml.sax.SAXException;
*/
public
class
BingAerialTileSource
extends
TMSTileSource
{
private
static
final
Logger
LOG
=
FeatureAdapter
.
getLogger
(
BingAerialTileSource
.
class
);
/** Setting key for Bing metadata API URL. Must contain {@link #API_KEY_PLACEHOLDER} */
public
static
final
String
METADATA_API_SETTING
=
"jmapviewer.bing.metadata-api-url"
;
/** Setting key for Bing API key */
public
static
final
String
API_KEY_SETTING
=
"jmapviewer.bing.api-key"
;
/** Placeholder to specify Bing API key in metadata API URL*/
public
static
final
String
API_KEY_PLACEHOLDER
=
"{apiKey}"
;
/** Bing Metadata API URL */
private
static
final
String
METADATA_API_URL
=
"https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&output=xml&key="
+
API_KEY_PLACEHOLDER
;
/** Original Bing API key created by Potlatch2 developers in 2010 */
private
static
final
String
API_KEY
=
"Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU"
;
private
static
volatile
Future
<
List
<
Attribution
>>
attributions
;
// volatile is required for getAttribution(), see below.
private
static
String
imageUrlTemplate
;
private
static
Integer
imageryZoomMax
;
...
...
@@ -94,8 +110,8 @@ public class BingAerialTileSource extends TMSTileSource {
}
protected
URL
getAttributionUrl
()
throws
MalformedURLException
{
return
new
URL
(
"https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&output=xml&key="
+
API_KEY
);
return
new
URL
(
FeatureAdapter
.
getSetting
(
METADATA_API_SETTING
,
METADATA_API_URL
)
.
replace
(
API_KEY_PLACEHOLDER
,
FeatureAdapter
.
getSetting
(
API_KEY_SETTING
,
API_KEY
)
))
;
}
protected
List
<
Attribution
>
parseAttributionText
(
InputSource
xml
)
throws
IOException
{
...
...
@@ -159,11 +175,8 @@ public class BingAerialTileSource extends TMSTileSource {
}
return
attributionsList
;
}
catch
(
SAXException
e
)
{
System
.
err
.
println
(
"Could not parse Bing aerials attribution metadata."
);
e
.
printStackTrace
();
}
catch
(
ParserConfigurationException
|
XPathExpressionException
|
NumberFormatException
e
)
{
e
.
printStackTrace
();
}
catch
(
SAXException
|
ParserConfigurationException
|
XPathExpressionException
|
NumberFormatException
e
)
{
LOG
.
log
(
Level
.
SEVERE
,
"Could not parse Bing aerials attribution metadata."
,
e
);
}
return
null
;
}
...
...
@@ -208,7 +221,7 @@ public class BingAerialTileSource extends TMSTileSource {
}
}
}
catch
(
IOException
e
)
{
System
.
err
.
println
(
"Error while retrieving Bing logo: "
+
e
.
getMessage
());
LOG
.
log
(
Level
.
SEVERE
,
"Error while retrieving Bing logo: "
+
e
.
getMessage
());
}
return
null
;
}
...
...
@@ -241,7 +254,7 @@ public class BingAerialTileSource extends TMSTileSource {
System
.
out
.
println
(
"Successfully loaded Bing attribution data."
);
return
r
;
}
catch
(
IOException
ex
)
{
System
.
err
.
println
(
"Could not connect to Bing API. Will retry in "
+
waitTimeSec
+
" seconds."
);
LOG
.
log
(
Level
.
SEVERE
,
"Could not connect to Bing API. Will retry in "
+
waitTimeSec
+
" seconds."
);
Thread
.
sleep
(
TimeUnit
.
SECONDS
.
toMillis
(
waitTimeSec
));
waitTimeSec
*=
2
;
}
...
...
@@ -264,11 +277,11 @@ public class BingAerialTileSource extends TMSTileSource {
try
{
return
attributions
.
get
(
0
,
TimeUnit
.
MILLISECONDS
);
}
catch
(
TimeoutException
ex
)
{
System
.
err
.
println
(
"Bing: attribution data is not yet loaded."
);
LOG
.
log
(
Level
.
WARNING
,
"Bing: attribution data is not yet loaded."
);
}
catch
(
ExecutionException
ex
)
{
throw
new
RuntimeException
(
ex
.
getCause
());
}
catch
(
InterruptedException
ign
)
{
System
.
err
.
println
(
"InterruptedException: "
+
ign
.
getMessage
());
LOG
.
log
(
Level
.
SEVERE
,
"InterruptedException: "
+
ign
.
getMessage
());
}
return
null
;
}
...
...