Commit 500d4915 authored by Deployer's avatar Deployer

Changed map component to OpenStreetMap 5.2

parent 2a31d2ca
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
version = "0.7.4"
group = "com.cedarmaps"
version = "1.0.0"
def siteUrl = 'http://cedarmaps.com'
def gitUrl = 'http://cedarmaps.com/git'
group = "com.cedarmaps"
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
versionCode 4
versionName "0.7.4"
}
buildTypes {
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile('com.mapbox.mapboxsdk:mapbox-android-sdk:0.7.4@aar') {
transitive = true
}
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'org.osmdroid:osmdroid-android:5.2@aar'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
}
install {
......@@ -62,22 +58,3 @@ install {
}
}
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives javadocJar
archives sourcesJar
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cedarstudios.cedarmapssdk">
<application android:allowBackup="true" android:label="@string/app_name">
<application android:allowBackup="true">
</application>
......
......@@ -4,9 +4,9 @@ package com.cedarstudios.cedarmapssdk;
import android.util.Pair;
import com.cedarstudios.cedarmapssdk.auth.OAuth2Support;
import com.mapbox.mapboxsdk.geometry.LatLng;
import org.json.JSONObject;
import org.osmdroid.api.IGeoPoint;
public interface CedarMaps extends OAuth2Support, CedarMapsBase {
......@@ -49,7 +49,7 @@ public interface CedarMaps extends OAuth2Support, CedarMapsBase {
* @return Results as JSONObject
* @throws CedarMapsException
*/
JSONObject geocode(String searchTerm, LatLng location, float distance) throws CedarMapsException;
JSONObject geocode(String searchTerm, IGeoPoint location, float distance) throws CedarMapsException;
/**
* Forward Geocoding. This API call needs a valid access token.
......@@ -61,7 +61,7 @@ public interface CedarMaps extends OAuth2Support, CedarMapsBase {
* @return Results as JSONObject
* @throws CedarMapsException
*/
JSONObject geocode(String searchTerm, LatLng location, float distance, String type) throws CedarMapsException;
JSONObject geocode(String searchTerm, IGeoPoint location, float distance, String type) throws CedarMapsException;
/**
* Forward Geocoding. This API call needs a valid access token.
......@@ -74,7 +74,7 @@ public interface CedarMaps extends OAuth2Support, CedarMapsBase {
* @return Results as JSONObject
* @throws CedarMapsException
*/
JSONObject geocode(String searchTerm, LatLng location, float distance, String type, int limit) throws CedarMapsException;
JSONObject geocode(String searchTerm, IGeoPoint location, float distance, String type, int limit) throws CedarMapsException;
/**
......@@ -90,10 +90,10 @@ public interface CedarMaps extends OAuth2Support, CedarMapsBase {
* @return Results as JSONObject
* @throws CedarMapsException
*/
JSONObject geocode(String searchTerm, LatLng location, float distance, LatLng ne, LatLng sw, String type, int limit) throws CedarMapsException;
JSONObject geocode(String searchTerm, IGeoPoint location, float distance, IGeoPoint ne, IGeoPoint sw, String type, int limit) throws CedarMapsException;
/**
* Gives an address based on a provided LatLng pair. This API call needs a valid access token.
* Gives an address based on a provided IGeoPoint pair. This API call needs a valid access token.
*
* @param lat
* @param lng
......@@ -111,7 +111,7 @@ public interface CedarMaps extends OAuth2Support, CedarMapsBase {
* @return Results as JSONObject
* @throws CedarMapsException
*/
JSONObject distance(LatLng location1, LatLng location2) throws CedarMapsException;
JSONObject distance(IGeoPoint location1, IGeoPoint location2) throws CedarMapsException;
/**
* This method calculates the distance between points in meters. It can be called with up to 15 pairs
......@@ -121,7 +121,7 @@ public interface CedarMaps extends OAuth2Support, CedarMapsBase {
* @return Results as JSONObject
* @throws CedarMapsException
*/
JSONObject distance(Pair<LatLng, LatLng>[] locationPairs) throws CedarMapsException;
JSONObject distance(Pair<IGeoPoint, IGeoPoint>[] locationPairs) throws CedarMapsException;
/**
* Gives all localities in a city wih geometry in GeoJSON format.
......
......@@ -99,8 +99,7 @@ abstract class CedarMapsBaseImpl implements CedarMapsBase, Serializable, OAuth2S
private OAuth2Support getOAuth2() {
if (!(auth instanceof OAuth2Support)) {
throw new IllegalStateException(
"OAuth client id/secret combination not supplied");
throw new IllegalStateException("OAuth client id/secret combination not supplied");
}
return (OAuth2Support) auth;
}
......
package com.cedarstudios.cedarmapssdk;
import com.squareup.okhttp.Response;
import java.io.IOException;
import okhttp3.Response;
public class CedarMapsException extends Exception {
private Response response;
......
......@@ -7,18 +7,19 @@ import com.cedarstudios.cedarmapssdk.auth.Authorization;
import com.cedarstudios.cedarmapssdk.auth.NullAuthorization;
import com.cedarstudios.cedarmapssdk.auth.OAuth2Authorization;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONException;
import org.json.JSONObject;
import org.osmdroid.api.IGeoPoint;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Locale;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
class CedarMapsImpl extends CedarMapsBaseImpl implements CedarMaps {
......@@ -42,22 +43,22 @@ class CedarMapsImpl extends CedarMapsBaseImpl implements CedarMaps {
}
@Override
public JSONObject geocode(String searchTerm, LatLng location, float distance) throws CedarMapsException {
public JSONObject geocode(String searchTerm, IGeoPoint location, float distance) throws CedarMapsException {
return geocode(searchTerm, location, distance, null, null, null, 30);
}
@Override
public JSONObject geocode(String searchTerm, LatLng location, float distance, String type) throws CedarMapsException {
public JSONObject geocode(String searchTerm, IGeoPoint location, float distance, String type) throws CedarMapsException {
return geocode(searchTerm, location, distance, null, null, type, 30);
}
@Override
public JSONObject geocode(String searchTerm, LatLng location, float distance, String type, int limit) throws CedarMapsException {
public JSONObject geocode(String searchTerm, IGeoPoint location, float distance, String type, int limit) throws CedarMapsException {
return geocode(searchTerm, location, distance, null, null, type, limit);
}
@Override
public JSONObject geocode(String searchTerm, LatLng location, float distance, LatLng ne, LatLng sw, String type, int limit)
public JSONObject geocode(String searchTerm, IGeoPoint location, float distance, IGeoPoint ne, IGeoPoint sw, String type, int limit)
throws CedarMapsException {
String term;
......@@ -114,7 +115,7 @@ class CedarMapsImpl extends CedarMapsBaseImpl implements CedarMaps {
}
@Override
public JSONObject distance(LatLng location1, LatLng location2) throws CedarMapsException {
public JSONObject distance(IGeoPoint location1, IGeoPoint location2) throws CedarMapsException {
if (TextUtils.isEmpty(conf.getMapId())) {
throw new CedarMapsException(new NullPointerException("mapId is null. please provide a mapId in configuration"));
}
......@@ -130,14 +131,14 @@ class CedarMapsImpl extends CedarMapsBaseImpl implements CedarMaps {
}
@Override
public JSONObject distance(Pair<LatLng, LatLng>[] locationPairs) throws CedarMapsException {
public JSONObject distance(Pair<IGeoPoint, IGeoPoint>[] locationPairs) throws CedarMapsException {
if (TextUtils.isEmpty(conf.getMapId())) {
throw new CedarMapsException(new NullPointerException("mapId is null. please provide a mapId in configuration"));
}
String pairs = "";
String delimiter = "";
for (Pair<LatLng, LatLng> locationPair : locationPairs) {
for (Pair<IGeoPoint, IGeoPoint> locationPair : locationPairs) {
pairs += delimiter + String.format(Locale.ENGLISH, "%1$s,%2$s;%3$s,%4$s", locationPair.first.getLatitude(),
locationPair.first.getLongitude(), locationPair.second.getLatitude(), locationPair.second.getLatitude());
delimiter = "/";
......
package com.cedarstudios.cedarmapssdk;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapsTileLayer;
import com.cedarstudios.cedarmapssdk.tileprovider.tilesource.CedarMapsTileSourceInfo;
public interface CedarMapsTileLayerListener {
void onPrepared(CedarMapsTileLayer tileLayer);
void onPrepared(CedarMapsTileSourceInfo tileLayer);
}
......@@ -3,16 +3,17 @@ package com.cedarstudios.cedarmapssdk.auth;
import com.cedarstudios.cedarmapssdk.CedarMapsException;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import org.json.JSONObject;
import java.io.Serializable;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class OAuth2Authorization implements Authorization, Serializable, OAuth2Support {
private final Configuration conf;
......@@ -41,7 +42,7 @@ public class OAuth2Authorization implements Authorization, Serializable, OAuth2S
}
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormEncodingBuilder()
RequestBody formBody = new FormBody.Builder()
.add("client_id", clientId)
.add("client_secret", clientSecret)
.build();
......
package com.cedarstudios.cedarmapssdk.tileprovider;
import android.content.Context;
import com.cedarstudios.cedarmapssdk.tileprovider.modules.CedarMapTileAssetsProvider;
import com.cedarstudios.cedarmapssdk.tileprovider.modules.CedarMapTileDownloader;
import com.cedarstudios.cedarmapssdk.tileprovider.modules.CedarMapTileFileArchiveProvider;
import com.cedarstudios.cedarmapssdk.tileprovider.modules.CedarMapTileFilesystemProvider;
import com.cedarstudios.cedarmapssdk.tileprovider.modules.CedarTileWriter;
import org.osmdroid.tileprovider.IRegisterReceiver;
import org.osmdroid.tileprovider.MapTileProviderBasic;
import org.osmdroid.tileprovider.modules.INetworkAvailablityCheck;
import org.osmdroid.tileprovider.modules.NetworkAvailabliltyCheck;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.util.SimpleRegisterReceiver;
public class CedarMapTileProvider extends MapTileProviderBasic {
public CedarMapTileProvider(Context pContext, ITileSource pTileSource) {
this(new SimpleRegisterReceiver(pContext), new NetworkAvailabliltyCheck(pContext), pTileSource, pContext);
}
public CedarMapTileProvider(IRegisterReceiver pRegisterReceiver, INetworkAvailablityCheck aNetworkAvailablityCheck, ITileSource pTileSource, Context pContext) {
super(pRegisterReceiver, aNetworkAvailablityCheck, pTileSource, pContext);
overrideTitleProviderList(pRegisterReceiver, aNetworkAvailablityCheck, pTileSource, pContext);
}
private void overrideTitleProviderList(IRegisterReceiver pRegisterReceiver, INetworkAvailablityCheck aNetworkAvailablityCheck, ITileSource pTileSource, Context pContext) {
mTileProviderList.clear();
final CedarTileWriter tileWriter = new CedarTileWriter();
final CedarMapTileAssetsProvider assetsProvider = new CedarMapTileAssetsProvider(pRegisterReceiver, pContext.getAssets(), pTileSource);
mTileProviderList.add(assetsProvider);
final CedarMapTileFilesystemProvider fileSystemProvider = new CedarMapTileFilesystemProvider(pRegisterReceiver, pTileSource);
mTileProviderList.add(fileSystemProvider);
final CedarMapTileFileArchiveProvider archiveProvider = new CedarMapTileFileArchiveProvider(pRegisterReceiver, pTileSource);
mTileProviderList.add(archiveProvider);
final CedarMapTileDownloader downloaderProvider = new CedarMapTileDownloader(pTileSource, tileWriter, aNetworkAvailablityCheck);
mTileProviderList.add(downloaderProvider);
}
}
package com.cedarstudios.cedarmapssdk.tileprovider.constants;
import android.os.Environment;
import android.util.Log;
import org.osmdroid.api.IMapView;
import org.osmdroid.tileprovider.LRUMapTileCache;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class CedarMapTileProviderConstants {
/**
* Base path for osmdroid files. Zip/sqlite/mbtiles/etc files are in this folder.
* Note: also used for offline tile sources
*/
private static File OSMDROID_PATH = new File(Environment.getExternalStorageDirectory(), ".cedarmap");
public static File getBasePath() {
return OSMDROID_PATH;
}
/**
* Base path for tiles.
* /sdcard/osmdroid/tiles
*/
public static File TILE_PATH_BASE = new File(OSMDROID_PATH, "tiles");
static {
try {
TILE_PATH_BASE.mkdirs();
new File(TILE_PATH_BASE + "/.nomedia").createNewFile();
} catch (Exception ex) {
Log.e(IMapView.LOGTAG, "unable to create a nomedia file. downloaded tiles may be visible to the gallery. " + ex.getMessage());
}
}
public static boolean DEBUGMODE = false;
public static boolean DEBUG_TILE_PROVIDERS = false;
public static String USER_AGENT = "User-Agent";
private static String USER_AGENT_VALUE = "CedarMap";
/**
* Enables you to get the value for HTTP user agents. Used when downloading tiles
*
* @return
* @since 5.0
*/
public static String getUserAgentValue() {
return USER_AGENT_VALUE;
}
/**
* Enables you to override the default "osmdroid" value for HTTP user agents. Used when downloading tiles
*
* @param val
* @since 5.0
*/
public static void setUserAgentValue(String val) {
USER_AGENT_VALUE = val;
}
/**
* Minimum Zoom Level
*/
public static final int MINIMUM_ZOOMLEVEL = 0;
/**
* add an extension to files on sdcard so that gallery doesn't index them
*/
public static final String TILE_PATH_EXTENSION = ".tile";
/**
* Initial tile cache size (in memory). The size will be increased as required by calling
* {@link LRUMapTileCache#ensureCapacity(int)} The tile cache will always be at least 3x3.
*/
public static int CACHE_MAPTILECOUNT_DEFAULT = 9;
/**
* number of tile download threads, conforming to OSM policy:
* http://wiki.openstreetmap.org/wiki/Tile_usage_policy
*/
private static int NUMBER_OF_TILE_DOWNLOAD_THREADS = 2;
public static int getNumberOfTileDownloadThreads() {
return NUMBER_OF_TILE_DOWNLOAD_THREADS;
}
/**
* Overrides the number of tile download threads. The default value is '2' conforming to OSM policy:
* http://wiki.openstreetmap.org/wiki/Tile_usage_policy
* <p/>
* Only use the value of '2' when connecting to OSM tile sources.
*
* @param threads
* @since 5.1
*/
public static void setNumberOfTileDownloadThreads(int threads) {
if (threads > 12)
NUMBER_OF_TILE_DOWNLOAD_THREADS = 12;
else if (threads < 1)
NUMBER_OF_TILE_DOWNLOAD_THREADS = 1;
else
NUMBER_OF_TILE_DOWNLOAD_THREADS = threads;
}
public static final short NUMBER_OF_TILE_FILESYSTEM_THREADS = 8;
public static final long ONE_SECOND = 1000;
public static final long ONE_MINUTE = ONE_SECOND * 60;
public static final long ONE_HOUR = ONE_MINUTE * 60;
public static final long ONE_DAY = ONE_HOUR * 24;
public static final long ONE_WEEK = ONE_DAY * 7;
public static final long ONE_YEAR = ONE_DAY * 365;
public static final long DEFAULT_MAXIMUM_CACHED_FILE_AGE = ONE_WEEK;
public static final short TILE_DOWNLOAD_MAXIMUM_QUEUE_SIZE = 40;
public static final short TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE = 40;
/**
* 30 days
*/
public static final long TILE_EXPIRY_TIME_MILLISECONDS = 1000L * 60 * 60 * 24 * 30;
/**
* default is 600 Mb
*/
public static long TILE_MAX_CACHE_SIZE_BYTES = 600L * 1024 * 1024;
/**
* default is 500 Mb
*/
public static long TILE_TRIM_CACHE_SIZE_BYTES = 500L * 1024 * 1024;
/**
* Change the root path of the osmdroid cache.
* By default, it is defined in SD card, osmdroid directory.
*
* @param newFullPath
*/
public static void setCachePath(String newFullPath) {
File f = new File(newFullPath);
if (f.exists()) {
TILE_PATH_BASE = f.getAbsoluteFile();
try {
new File(TILE_PATH_BASE + "/.nomedia").createNewFile();
} catch (Exception ex) {
Log.e(IMapView.LOGTAG, "unable to create a nomedia file. downloaded tiles may be visible to the gallery.", ex);
}
}
}
/**
* Change the osmdroid tiles cache sizes. (note this represents size of the cache on disk, not in memory)
*
* @param maxCacheSize in Mb. Default is 600 Mb.
* @param trimCacheSize When the cache size exceeds maxCacheSize, tiles will be automatically removed to reach this target. In Mb. Default is 500 Mb.
* @author MKer
* @since 4.4
*/
public static void setCacheSizes(long maxCacheSize, long trimCacheSize) {
TILE_MAX_CACHE_SIZE_BYTES = maxCacheSize * 1024 * 1024;
TILE_TRIM_CACHE_SIZE_BYTES = trimCacheSize * 1024 * 1024;
}
/**
* allows for altering the osmdroid_path variable, which controls the location
* of where to search for offline tile sources
*
* @param path
*/
public static void setOfflineMapsPath(String path) {
OSMDROID_PATH = new File(path);
}
/**
* @since 5.1
*/
public static final String HTTP_EXPIRES_HEADER = "Expires";
/**
* @since 5.1
*/
public static final String HTTP_EXPIRES_HEADER_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z";
/**
* used for HTTP expires headers
*
* @since 5.1
*/
public static final SimpleDateFormat HTTP_HEADER_SDF = new SimpleDateFormat(HTTP_EXPIRES_HEADER_FORMAT, Locale.US);
}
\ No newline at end of file
package com.cedarstudios.cedarmapssdk.tileprovider.modules;
import android.content.res.AssetManager;
import android.graphics.drawable.Drawable;
import com.cedarstudios.cedarmapssdk.tileprovider.constants.CedarMapTileProviderConstants;
import org.osmdroid.tileprovider.IRegisterReceiver;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.MapTileRequestState;
import org.osmdroid.tileprovider.modules.MapTileFileStorageProviderBase;
import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase;
import org.osmdroid.tileprovider.tilesource.BitmapTileSourceBase.LowMemoryException;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicReference;
public class CedarMapTileAssetsProvider extends MapTileFileStorageProviderBase {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final AssetManager mAssets;
private final AtomicReference<ITileSource> mTileSource = new AtomicReference<ITileSource>();
// ===========================================================
// Constructors
// ===========================================================
public CedarMapTileAssetsProvider(final IRegisterReceiver pRegisterReceiver, final AssetManager pAssets) {
this(pRegisterReceiver, pAssets, TileSourceFactory.DEFAULT_TILE_SOURCE);
}
public CedarMapTileAssetsProvider(final IRegisterReceiver pRegisterReceiver,
final AssetManager pAssets,
final ITileSource pTileSource) {
this(pRegisterReceiver, pAssets, pTileSource,
CedarMapTileProviderConstants.getNumberOfTileDownloadThreads(),
CedarMapTileProviderConstants.TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE);
}
public CedarMapTileAssetsProvider(final IRegisterReceiver pRegisterReceiver,
final AssetManager pAssets,
final ITileSource pTileSource, int pThreadPoolSize,
int pPendingQueueSize) {
super(pRegisterReceiver, pThreadPoolSize, pPendingQueueSize);
setTileSource(pTileSource);
mAssets = pAssets;
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods from SuperClass/Interfaces
// ===========================================================
@Override
public boolean getUsesDataConnection() {
return false;
}
@Override
protected String getName() {
return "Assets Cache Provider";
}
@Override
protected String getThreadGroupName() {
return "assets";
}
@Override
protected Runnable getTileLoader() {
return new TileLoader(mAssets);
}
@Override
public int getMinimumZoomLevel() {
ITileSource tileSource = mTileSource.get();
return tileSource != null ? tileSource.getMinimumZoomLevel() : CedarMapTileProviderConstants.MINIMUM_ZOOMLEVEL;
}
@Override
public int getMaximumZoomLevel() {
ITileSource tileSource = mTileSource.get();
return tileSource != null ? tileSource.getMaximumZoomLevel()
: microsoft.mappoint.TileSystem.getMaximumZoomLevel();
}
@Override
public void setTileSource(final ITileSource pTileSource) {
mTileSource.set(pTileSource);
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
protected class TileLoader extends MapTileModuleProviderBase.TileLoader {
private AssetManager mAssets = null;
public TileLoader(AssetManager pAssets) {
mAssets = pAssets;
}
@Override
public Drawable loadTile(final MapTileRequestState pState) throws CantContinueException {
ITileSource tileSource = mTileSource.get();
if (tileSource == null) {
return null;
}
final MapTile tile = pState.getMapTile();
try {
InputStream is = mAssets.open(tileSource.getTileRelativeFilenameString(tile));
final Drawable drawable = tileSource.getDrawable(is);
if (drawable != null) {
//https://github.com/osmdroid/osmdroid/issues/272 why was this set to expired?
//ExpirableBitmapDrawable.setDrawableExpired(drawable);
}
return drawable;
} catch (IOException e) {
} catch (final LowMemoryException e) {
throw new CantContinueException(e);
}
// If we get here then there is no file in the file cache
return null;
}
}
}
package com.cedarstudios.cedarmapssdk.tileprovider.modules;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
import com.cedarstudios.cedarmapssdk.CedarMaps;
import com.cedarstudios.cedarmapssdk.CedarMapsException;
import com.cedarstudios.cedarmapssdk.CedarMapsFactory;
import com.cedarstudios.cedarmapssdk.auth.OAuth2Token;
import com.cedarstudios.cedarmapssdk.tileprovider.constants.CedarMapTileProviderConstants;
import com.cedarstudios.cedarmapssdk.tileprovider.tilesource.CedarMapsTileSource;
import com.cedarstudios.cedarmapssdk.utils.CedarMapsUtils;
import org.osmdroid.api.IMapView;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.MapTileRequestState;
import org.osmdroid.tileprovider.modules.IFilesystemCache;
import org.osmdroid.tileprovider.modules.INetworkAvailablityCheck;
import org.osmdroid.tileprovider.modules.MapTileDownloader;
import org.osmdroid.tileprovider.tilesource.BitmapTileSourceBase;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase;
import org.osmdroid.tileprovider.util.StreamUtils;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.concurrent.atomic.AtomicReference;
public class CedarMapTileDownloader extends MapTileDownloader {
private final IFilesystemCache mFilesystemCache;
private final AtomicReference<OnlineTileSourceBase> mTileSource = new AtomicReference<>();
private final INetworkAvailablityCheck mNetworkAvailablityCheck;
public CedarMapTileDownloader(ITileSource pTileSource, IFilesystemCache pFilesystemCache, INetworkAvailablityCheck pNetworkAvailablityCheck) {
super(pTileSource, pFilesystemCache, pNetworkAvailablityCheck);
mFilesystemCache = pFilesystemCache;
mNetworkAvailablityCheck = pNetworkAvailablityCheck;
setCedarTileSource(pTileSource);
}
@Override
public ITileSource getTileSource() {
return mTileSource.get();
}
public void setCedarTileSource(final ITileSource tileSource) {
super.setTileSource(tileSource);
// We are only interested in OnlineTileSourceBase tile sources
if (tileSource instanceof OnlineTileSourceBase) {
mTileSource.set((OnlineTileSourceBase) tileSource);
} else {
// Otherwise shut down the tile downloader
mTileSource.set(null);
}
}
@Override
protected Runnable getTileLoader() {
return new CedarTileLoader();
}
protected class CedarTileLoader extends TileLoader {
@Override
public Drawable loadTile(MapTileRequestState aState) throws CantContinueException {
OnlineTileSourceBase tileSource = mTileSource.get();
if (tileSource == null) {
return null;
}
InputStream in = null;
OutputStream out = null;
HttpURLConnection c = null;
final MapTile tile = aState.getMapTile();
try {
if (mNetworkAvailablityCheck != null
&& !mNetworkAvailablityCheck.getNetworkAvailable()) {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "Skipping " + getName() + " due to NetworkAvailabliltyCheck.");
}
return null;
}
final String tileURLString = tileSource.getTileURLString(tile);
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "Downloading Maptile from url: " + tileURLString);
}
if (TextUtils.isEmpty(tileURLString)) {
return null;
}
c = (HttpURLConnection) new URL(tileURLString).openConnection();
c.setUseCaches(true);
c.setRequestProperty(CedarMapTileProviderConstants.USER_AGENT, CedarMapTileProviderConstants.getUserAgentValue());
c.connect();
// Check to see if we got success
if (c.getResponseCode() != 200) {
Log.w(IMapView.LOGTAG, "Problem downloading MapTile: " + tile + " HTTP response: " + c.getResponseMessage());
if (c.getResponseCode() == 401) {
CedarMapsFactory factory = new CedarMapsFactory(((CedarMapsTileSource) mTileSource.get()).getConfiguration());
CedarMaps cedarMaps = factory.getInstance();
try {
OAuth2Token oAuth2Token = cedarMaps.getOAuth2Token();
CedarMapsUtils.setAccessToken(oAuth2Token.getAccessToken());
((CedarMapsTileSource) mTileSource.get()).setAccessToken(oAuth2Token.getAccessToken());
loadTile(aState);
} catch (CedarMapsException e) {
e.printStackTrace();
}
}
return null;
}
in = c.getInputStream();
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, StreamUtils.IO_BUFFER_SIZE);
Date dateExpires = new Date(System.currentTimeMillis() + MAX_CACHED_TILE_AGE);
final String expires = c.getHeaderField(CedarMapTileProviderConstants.HTTP_EXPIRES_HEADER);
if (expires != null && expires.length() > 0) {
try {
dateExpires = CedarMapTileProviderConstants.HTTP_HEADER_SDF.parse(expires);
} catch (Exception ex) {
if (DEBUG)
Log.d(IMapView.LOGTAG, "Unable to parse expiration tag for tile, using default, server returned " + expires, ex);
}
}
tile.setExpires(dateExpires);
StreamUtils.copy(in, out);
out.flush();
final byte[] data = dataStream.toByteArray();
final ByteArrayInputStream byteStream = new ByteArrayInputStream(data);
// Save the data to the filesystem cache
if (mFilesystemCache != null) {
mFilesystemCache.saveFile(tileSource, tile, byteStream);
byteStream.reset();
}
final Drawable result = tileSource.getDrawable(byteStream);
return result;
} catch (final UnknownHostException e) {
// no network connection so empty the queue
Log.w(IMapView.LOGTAG, "UnknownHostException downloading MapTile: " + tile + " : " + e);
throw new CantContinueException(e);
} catch (final BitmapTileSourceBase.LowMemoryException e) {
// low memory so empty the queue
Log.w(IMapView.LOGTAG, "LowMemoryException downloading MapTile: " + tile + " : " + e);
throw new CantContinueException(e);
} catch (final FileNotFoundException e) {
Log.w(IMapView.LOGTAG, "Tile not found: " + tile + " : " + e);
} catch (final IOException e) {
Log.w(IMapView.LOGTAG, "IOException downloading MapTile: " + tile + " : " + e);
} catch (final Throwable e) {
Log.e(IMapView.LOGTAG, "Error downloading MapTile: " + tile, e);
} finally {
StreamUtils.closeStream(in);
StreamUtils.closeStream(out);
try {
c.disconnect();
} catch (Exception ex) {
}
}
return null;
}
}
}
package com.cedarstudios.cedarmapssdk.tileprovider.modules;
import android.graphics.drawable.Drawable;
import android.util.Log;
import com.cedarstudios.cedarmapssdk.tileprovider.constants.CedarMapTileProviderConstants;
import org.osmdroid.api.IMapView;
import org.osmdroid.tileprovider.IRegisterReceiver;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.MapTileProviderBase;
import org.osmdroid.tileprovider.MapTileRequestState;
import org.osmdroid.tileprovider.modules.ArchiveFileFactory;
import org.osmdroid.tileprovider.modules.IArchiveFile;
import org.osmdroid.tileprovider.modules.MapTileFileStorageProviderBase;
import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.util.StreamUtils;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicReference;
public class CedarMapTileFileArchiveProvider extends MapTileFileStorageProviderBase {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final ArrayList<IArchiveFile> mArchiveFiles = new ArrayList<IArchiveFile>();
private final AtomicReference<ITileSource> mTileSource = new AtomicReference<ITileSource>();
/**
* Disable the search of archives if specified in constructor
*/
private final boolean mSpecificArchivesProvided;
// ===========================================================
// Constructors
// ===========================================================
/**
* The tiles may be found on several media. This one works with tiles stored on the file system.
* It and its friends are typically created and controlled by {@link MapTileProviderBase}.
*/
public CedarMapTileFileArchiveProvider(final IRegisterReceiver pRegisterReceiver,
final ITileSource pTileSource, final IArchiveFile[] pArchives) {
super(pRegisterReceiver, CedarMapTileProviderConstants.NUMBER_OF_TILE_FILESYSTEM_THREADS,
CedarMapTileProviderConstants.TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE);
setTileSource(pTileSource);
if (pArchives == null) {
mSpecificArchivesProvided = false;
findArchiveFiles();
} else {
mSpecificArchivesProvided = true;
for (int i = pArchives.length - 1; i >= 0; i--) {
mArchiveFiles.add(pArchives[i]);
}
}
}
public CedarMapTileFileArchiveProvider(final IRegisterReceiver pRegisterReceiver,
final ITileSource pTileSource) {
this(pRegisterReceiver, pTileSource, null);
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods from SuperClass/Interfaces
// ===========================================================
@Override
public boolean getUsesDataConnection() {
return false;
}
@Override
protected String getName() {
return "File Archive Provider";
}
@Override
protected String getThreadGroupName() {
return "filearchive";
}
@Override
protected Runnable getTileLoader() {
return new TileLoader();
}
@Override
public int getMinimumZoomLevel() {
ITileSource tileSource = mTileSource.get();
return tileSource != null ? tileSource.getMinimumZoomLevel() : CedarMapTileProviderConstants.MINIMUM_ZOOMLEVEL;
}
@Override
public int getMaximumZoomLevel() {
ITileSource tileSource = mTileSource.get();
return tileSource != null ? tileSource.getMaximumZoomLevel()
: microsoft.mappoint.TileSystem.getMaximumZoomLevel();
}
@Override
protected void onMediaMounted() {
if (!mSpecificArchivesProvided) {
findArchiveFiles();
}
}
@Override
protected void onMediaUnmounted() {
if (!mSpecificArchivesProvided) {
findArchiveFiles();
}
}
@Override
public void setTileSource(final ITileSource pTileSource) {
mTileSource.set(pTileSource);
}
@Override
public void detach() {
while (!mArchiveFiles.isEmpty()) {
IArchiveFile t = mArchiveFiles.get(0);
if (t != null)
mArchiveFiles.get(0).close();
mArchiveFiles.remove(0);
}
super.detach();
}
// ===========================================================
// Methods
// ===========================================================
private void findArchiveFiles() {
mArchiveFiles.clear();
if (!getSdCardAvailable()) {
return;
}
// path should be optionally configurable
File cachePaths = CedarMapTileProviderConstants.getBasePath();
final File[] files = cachePaths.listFiles();
if (files != null) {
for (final File file : files) {
final IArchiveFile archiveFile = ArchiveFileFactory.getArchiveFile(file);
if (archiveFile != null) {
mArchiveFiles.add(archiveFile);
}
}
}
}
private synchronized InputStream getInputStream(final MapTile pTile,
final ITileSource tileSource) {
for (final IArchiveFile archiveFile : mArchiveFiles) {
if (archiveFile != null) {
final InputStream in = archiveFile.getInputStream(tileSource, pTile);
if (in != null) {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "Found tile " + pTile + " in " + archiveFile);
}
return in;
}
}
}
return null;
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
protected class TileLoader extends MapTileModuleProviderBase.TileLoader {
@Override
public Drawable loadTile(final MapTileRequestState pState) {
ITileSource tileSource = mTileSource.get();
if (tileSource == null) {
return null;
}
final MapTile pTile = pState.getMapTile();
// if there's no sdcard then don't do anything
if (!getSdCardAvailable()) {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "No sdcard - do nothing for tile: " + pTile);
}
return null;
}
InputStream inputStream = null;
try {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "Tile doesn't exist: " + pTile);
}
inputStream = getInputStream(pTile, tileSource);
if (inputStream != null) {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "Use tile from archive: " + pTile);
}
final Drawable drawable = tileSource.getDrawable(inputStream);
return drawable;
}
} catch (final Throwable e) {
Log.e(IMapView.LOGTAG, "Error loading tile", e);
} finally {
if (inputStream != null) {
StreamUtils.closeStream(inputStream);
}
}
return null;
}
}
}
\ No newline at end of file
package com.cedarstudios.cedarmapssdk.tileprovider.modules;
import android.graphics.drawable.Drawable;
import android.util.Log;
import com.cedarstudios.cedarmapssdk.tileprovider.constants.CedarMapTileProviderConstants;
import org.osmdroid.api.IMapView;
import org.osmdroid.tileprovider.ExpirableBitmapDrawable;
import org.osmdroid.tileprovider.IRegisterReceiver;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.MapTileRequestState;
import org.osmdroid.tileprovider.modules.DatabaseFileArchive;
import org.osmdroid.tileprovider.modules.MapTileFileStorageProviderBase;
import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase;
import org.osmdroid.tileprovider.tilesource.BitmapTileSourceBase.LowMemoryException;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import java.io.File;
import java.util.concurrent.atomic.AtomicReference;
public class CedarMapTileFilesystemProvider extends MapTileFileStorageProviderBase {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
private final long mMaximumCachedFileAge;
private DatabaseFileArchive databaseFileArchive;
private final AtomicReference<ITileSource> mTileSource = new AtomicReference<ITileSource>();
// ===========================================================
// Constructors
// ===========================================================
public CedarMapTileFilesystemProvider(final IRegisterReceiver pRegisterReceiver) {
this(pRegisterReceiver, TileSourceFactory.DEFAULT_TILE_SOURCE);
}
public CedarMapTileFilesystemProvider(final IRegisterReceiver pRegisterReceiver,
final ITileSource aTileSource) {
this(pRegisterReceiver, aTileSource, CedarMapTileProviderConstants.DEFAULT_MAXIMUM_CACHED_FILE_AGE);
}
public CedarMapTileFilesystemProvider(final IRegisterReceiver pRegisterReceiver,
final ITileSource pTileSource, final long pMaximumCachedFileAge) {
this(pRegisterReceiver, pTileSource, pMaximumCachedFileAge,
CedarMapTileProviderConstants.NUMBER_OF_TILE_FILESYSTEM_THREADS,
CedarMapTileProviderConstants.TILE_FILESYSTEM_MAXIMUM_QUEUE_SIZE);
}
/**
* Provides a file system based cache tile provider. Other providers can register and store data
* in the cache.
*
* @param pRegisterReceiver
*/
public CedarMapTileFilesystemProvider(final IRegisterReceiver pRegisterReceiver,
final ITileSource pTileSource, final long pMaximumCachedFileAge, int pThreadPoolSize,
int pPendingQueueSize) {
super(pRegisterReceiver, pThreadPoolSize, pPendingQueueSize);
setTileSource(pTileSource);
mMaximumCachedFileAge = pMaximumCachedFileAge;
}
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods from SuperClass/Interfaces
// ===========================================================
@Override
public boolean getUsesDataConnection() {
return false;
}
@Override
protected String getName() {
return "File System Cache Provider";
}
@Override
protected String getThreadGroupName() {
return "filesystem";
}
@Override
protected Runnable getTileLoader() {
return new TileLoader();
}
@Override
public int getMinimumZoomLevel() {
ITileSource tileSource = mTileSource.get();
return tileSource != null ? tileSource.getMinimumZoomLevel() : CedarMapTileProviderConstants.MINIMUM_ZOOMLEVEL;
}
@Override
public int getMaximumZoomLevel() {
ITileSource tileSource = mTileSource.get();
return tileSource != null ? tileSource.getMaximumZoomLevel()
: microsoft.mappoint.TileSystem.getMaximumZoomLevel();
}
@Override
public void setTileSource(final ITileSource pTileSource) {
mTileSource.set(pTileSource);
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
protected class TileLoader extends MapTileModuleProviderBase.TileLoader {
@Override
public Drawable loadTile(final MapTileRequestState pState) throws CantContinueException {
ITileSource tileSource = mTileSource.get();
if (tileSource == null) {
return null;
}
final MapTile tile = pState.getMapTile();
// if there's no sdcard then don't do anything
if (!getSdCardAvailable()) {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "No sdcard - do nothing for tile: " + tile);
}
return null;
}
// Check the tile source to see if its file is available and if so, then render the
// drawable and return the tile
final File file = new File(CedarMapTileProviderConstants.TILE_PATH_BASE,
tileSource.getTileRelativeFilenameString(tile) + CedarMapTileProviderConstants.TILE_PATH_EXTENSION);
if (file.exists()) {
try {
final Drawable drawable = tileSource.getDrawable(file.getPath());
// Check to see if file has expired
final long now = System.currentTimeMillis();
final long lastModified = file.lastModified();
final boolean fileExpired = lastModified < now - mMaximumCachedFileAge;
if (fileExpired && drawable != null) {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "Tile expired: " + tile);
}
ExpirableBitmapDrawable.setDrawableExpired(drawable);
}
return drawable;
} catch (final LowMemoryException e) {
// low memory so empty the queue
Log.w(IMapView.LOGTAG, "LowMemoryException downloading MapTile: " + tile + " : " + e);
throw new CantContinueException(e);
}
}
// If we get here then there is no file in the file cache
return null;
}
}
}
package com.cedarstudios.cedarmapssdk.tileprovider.modules;
import android.util.Log;
import com.cedarstudios.cedarmapssdk.tileprovider.constants.CedarMapTileProviderConstants;
import org.osmdroid.api.IMapView;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.modules.IFilesystemCache;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.util.StreamUtils;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.NoSuchElementException;
public class CedarTileWriter implements IFilesystemCache {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Fields
// ===========================================================
/** amount of disk space used by tile cache **/
private static long mUsedCacheSpace;
static boolean hasInited=false;
// ===========================================================
// Constructors
// ===========================================================
public CedarTileWriter() {
if (!hasInited) {
hasInited = true;
// do this in the background because it takes a long time
final Thread t = new Thread() {
@Override
public void run() {
mUsedCacheSpace = 0; // because it's static
calculateDirectorySize(CedarMapTileProviderConstants.TILE_PATH_BASE);
if (mUsedCacheSpace > CedarMapTileProviderConstants.TILE_MAX_CACHE_SIZE_BYTES) {
cutCurrentCache();
}
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG, "Finished init thread");
}
}
};
t.setPriority(Thread.MIN_PRIORITY);
t.start();
}
}
// ===========================================================
// Getter & Setter
// ===========================================================
/**
* Get the amount of disk space used by the tile cache. This will initially be zero since the
* used space is calculated in the background.
*
* @return size in bytes
*/
public static long getUsedCacheSpace() {
return mUsedCacheSpace;
}
// ===========================================================
// Methods from SuperClass/Interfaces
// ===========================================================
@Override
public boolean saveFile(final ITileSource pTileSource, final MapTile pTile,
final InputStream pStream) {
final File file = new File(CedarMapTileProviderConstants.TILE_PATH_BASE, pTileSource.getTileRelativeFilenameString(pTile)
+ CedarMapTileProviderConstants.TILE_PATH_EXTENSION);
if (CedarMapTileProviderConstants.DEBUG_TILE_PROVIDERS){
Log.d(IMapView.LOGTAG, "TileWrite " + file.getAbsolutePath());
}
final File parent = file.getParentFile();
if (!parent.exists() && !createFolderAndCheckIfExists(parent)) {
return false;
}
BufferedOutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(new FileOutputStream(file.getPath()),
StreamUtils.IO_BUFFER_SIZE);
final long length = StreamUtils.copy(pStream, outputStream);
mUsedCacheSpace += length;
if (mUsedCacheSpace > CedarMapTileProviderConstants.TILE_MAX_CACHE_SIZE_BYTES) {
cutCurrentCache(); // TODO perhaps we should do this in the background
}
} catch (final IOException e) {
return false;
} finally {
if (outputStream != null) {
StreamUtils.closeStream(outputStream);
}
}
return true;
}
// ===========================================================
// Methods
// ===========================================================
private boolean createFolderAndCheckIfExists(final File pFile) {
if (pFile.mkdirs()) {
return true;
}
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG,"Failed to create " + pFile + " - wait and check again");
}
// if create failed, wait a bit in case another thread created it
try {
Thread.sleep(500);
} catch (final InterruptedException ignore) {
}
// and then check again
if (pFile.exists()) {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG,"Seems like another thread created " + pFile);
}
return true;
} else {
if (CedarMapTileProviderConstants.DEBUGMODE) {
Log.d(IMapView.LOGTAG,"File still doesn't exist: " + pFile);
}
return false;
}
}
private void calculateDirectorySize(final File pDirectory) {
final File[] z = pDirectory.listFiles();
if (z != null) {
for (final File file : z) {
if (file.isFile()) {
mUsedCacheSpace += file.length();
}
if (file.isDirectory() && !isSymbolicDirectoryLink(pDirectory, file)) {
calculateDirectorySize(file); // *** recurse ***
}
}
}
}
/**
* Checks to see if it appears that a directory is a symbolic link. It does this by comparing
* the canonical path of the parent directory and the parent directory of the directory's
* canonical path. If they are equal, then they come from the same true parent. If not, then
* pDirectory is a symbolic link. If we get an exception, we err on the side of caution and
* return "true" expecting the calculateDirectorySize to now skip further processing since
* something went goofy.
*/
private boolean isSymbolicDirectoryLink(final File pParentDirectory, final File pDirectory) {
try {
final String canonicalParentPath1 = pParentDirectory.getCanonicalPath();
final String canonicalParentPath2 = pDirectory.getCanonicalFile().getParent();
return !canonicalParentPath1.equals(canonicalParentPath2);
} catch (final IOException e) {
return true;
} catch (final NoSuchElementException e) {
// See: http://code.google.com/p/android/issues/detail?id=4961
// See: http://code.google.com/p/android/issues/detail?id=5807
return true;
}
}
private List<File> getDirectoryFileList(final File aDirectory) {
final List<File> files = new ArrayList<File>();
final File[] z = aDirectory.listFiles();
if (z != null) {
for (final File file : z) {
if (file.isFile()) {
files.add(file);
}
if (file.isDirectory()) {
files.addAll(getDirectoryFileList(file));
}
}
}
return files;
}
/**
* If the cache size is greater than the max then trim it down to the trim level. This method is
* synchronized so that only one thread can run it at a time.
*/
private void cutCurrentCache() {
final File lock=CedarMapTileProviderConstants.TILE_PATH_BASE;
synchronized (lock) {
if (mUsedCacheSpace > CedarMapTileProviderConstants.TILE_TRIM_CACHE_SIZE_BYTES) {
Log.d(IMapView.LOGTAG,"Trimming tile cache from " + mUsedCacheSpace + " to "
+ CedarMapTileProviderConstants.TILE_TRIM_CACHE_SIZE_BYTES);
final List<File> z = getDirectoryFileList(CedarMapTileProviderConstants.TILE_PATH_BASE);
// order list by files day created from old to new
final File[] files = z.toArray(new File[0]);
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(final File f1, final File f2) {
return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
}
});
for (final File file : files) {
if (mUsedCacheSpace <= CedarMapTileProviderConstants.TILE_TRIM_CACHE_SIZE_BYTES) {
break;
}
final long length = file.length();
if (file.delete()) {
if (CedarMapTileProviderConstants.DEBUG_TILE_PROVIDERS){
Log.d(IMapView.LOGTAG,"Cache trim deleting " + file.getAbsolutePath());
}
mUsedCacheSpace -= length;
}
}
Log.d(IMapView.LOGTAG,"Finished trimming tile cache");
}
}
}
}
\ No newline at end of file
package com.cedarstudios.cedarmapssdk.tileprovider.tilesource;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase;
import org.osmdroid.util.BoundingBoxE6;
public class CedarMapsTileSource extends OnlineTileSourceBase {
private String mMapId = "";
private String mAccessToken;
private CedarMapsTileSourceInfo mTileSourceInfo;
public CedarMapsTileSource() { // only for early initialization. should use CedarMapsTileSource with params
super("", 11, 18, 256, ".png", new String[]{});
}
public CedarMapsTileSource(CedarMapsTileSourceInfo tileLayer) {
super(tileLayer.getName(), tileLayer.getMinimumZoomLevel(), tileLayer.getMaximumZoomLevel(),
tileLayer.getTitleSize(), tileLayer.getImageExtension(), new String[]{tileLayer.getBaseUrl()});
mMapId = tileLayer.getMapId();
mAccessToken = tileLayer.getAccessToken();
mTileSourceInfo = tileLayer;
}
@Override
public String getTileURLString(final MapTile aMapTile) {
String url = getBaseUrl() +
mMapId +
"/" +
aMapTile.getZoomLevel() +
"/" +
aMapTile.getX() +
"/" +
aMapTile.getY() +
mTileSourceInfo.getImageExtension() +
"?access_token=" + mAccessToken;
return url;
}
public BoundingBoxE6 getBoundingBox() {
return mTileSourceInfo.getBoundingBox();
}
public Configuration getConfiguration() {
return mTileSourceInfo.getConfiguration();
}
public void setAccessToken(String accessToken) {
this.mAccessToken = accessToken;
}
}
\ No newline at end of file
package com.cedarstudios.cedarmapssdk.utils;
import com.mapbox.mapboxsdk.util.MapboxUtils;
import android.text.TextUtils;
public class CedarMapsUtils extends MapboxUtils {
public class CedarMapsUtils {
private static String accessToken = null;
public static String getAccessToken() {
if (TextUtils.isEmpty(accessToken)) {
return null;
}
return accessToken;
}
public static void setAccessToken(String accessToken) {
CedarMapsUtils.accessToken = accessToken;
}
}
\ No newline at end of file
package com.cedarstudios.cedarmapssdk.utils;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.cedarstudios.cedarmapssdk.BuildConfig;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.SSLSocketFactory;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import okhttp3.OkUrlFactory;
public class NetworkUtils {
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
public static HttpURLConnection getHttpURLConnection(final URL url) {
return getHttpURLConnection(url, null, null);
}
public static HttpURLConnection getHttpURLConnection(final URL url, final Cache cache) {
return getHttpURLConnection(url, cache, null);
}
public static HttpURLConnection getHttpURLConnection(final URL url, final Cache cache, final SSLSocketFactory sslSocketFactory) {
OkHttpClient client = new OkHttpClient();
HttpURLConnection connection = new OkUrlFactory(client).open(url);
connection.setRequestProperty("User-Agent", getUserAgent());
return connection;
}
public static Cache getCache(final File cacheDir, final int maxSize) throws IOException {
return new Cache(cacheDir, maxSize);
}
public static String getUserAgent() {
StringBuilder sb = new StringBuilder("CedarMaps Android SDK");
sb.append("/");
sb.append(BuildConfig.VERSION_NAME);
return sb.toString();
}
}
\ No newline at end of file
package com.cedarstudios.cedarmapssdk.view;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapTileProvider;
import com.cedarstudios.cedarmapssdk.tileprovider.tilesource.CedarMapsTileSource;
import org.osmdroid.tileprovider.MapTile;
import org.osmdroid.tileprovider.MapTileProviderBase;
public class MapView extends org.osmdroid.views.MapView {
protected MapView(Context context, MapTileProviderBase tileProvider, Handler tileRequestCompleteHandler, AttributeSet attrs) {
super(context, tileProvider, tileRequestCompleteHandler, attrs);
}
public MapView(Context context, AttributeSet attrs) {
this(context, new FakeTileProvider(), null, attrs);
}
public MapView(Context context) {
super(context);
}
public MapView(Context context, MapTileProviderBase aTileProvider) {
super(context, aTileProvider);
}
public MapView(Context context, MapTileProviderBase aTileProvider, Handler tileRequestCompleteHandler) {
super(context, aTileProvider, tileRequestCompleteHandler);
}
@Override
public void setTileProvider(MapTileProviderBase base) {
super.setTileProvider(base);
if (base instanceof CedarMapTileProvider) {
CedarMapsTileSource cedarMapsTileSource = (CedarMapsTileSource) base.getTileSource();
setScrollableAreaLimit(cedarMapsTileSource.getBoundingBox());
invalidate();
setMinZoomLevel(cedarMapsTileSource.getMinimumZoomLevel());
setMaxZoomLevel(cedarMapsTileSource.getMaximumZoomLevel());
setMultiTouchControls(true);
}
}
static class FakeTileProvider extends MapTileProviderBase {
public FakeTileProvider() {
super(new CedarMapsTileSource());
}
@Override
public Drawable getMapTile(MapTile pTile) {
return null;
}
@Override
public void detach() {
}
@Override
public int getMinimumZoomLevel() {
return 0;
}
@Override
public int getMaximumZoomLevel() {
return 0;
}
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion "21.1.2"
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.cedarstudios.cedarmaps.sample"
......@@ -21,6 +21,7 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.1.1'
compile(project(':CedarMapsSDK'))
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cedarstudios.cedarmaps.sample" >
<manifest package="com.cedarstudios.cedarmaps.sample"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
......@@ -12,15 +12,16 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|uiMode"
android:label="@string/app_name" >
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
......
package com.cedarstudios.cedarmaps.sample;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import com.cedarstudios.cedarmaps.sample.fragment.APIAdvancedGeocodeTestFragment;
import com.cedarstudios.cedarmaps.sample.fragment.APIGeocodeTestFragment;
import com.cedarstudios.cedarmaps.sample.fragment.APIReverseGeocodeTestFragment;
......@@ -12,35 +29,9 @@ import com.cedarstudios.cedarmapssdk.CedarMapsFactory;
import com.cedarstudios.cedarmapssdk.auth.OAuth2Token;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends ActionBarActivity {
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private ListView mDrawerList;
private ArrayList<String> testFragmentNames;
private int selectedFragmentIndex = 0;
public static final String PREF_NAME = "pref";
......@@ -51,115 +42,58 @@ public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
MapView.setDebugMode(true); //make sure to call this before the view is created!
*/
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Set the adapter for the list view
testFragmentNames = new ArrayList<>();
testFragmentNames.add(getString(R.string.mainTestMap));
testFragmentNames.add(getString(R.string.markersTestMap));
testFragmentNames.add(getString(R.string.itemizedOverlayTestMap));
testFragmentNames.add(getString(R.string.searchAPI));
testFragmentNames.add(getString(R.string.streetSearchAPIAdvanced));
testFragmentNames.add(getString(R.string.reverseGeocode));
mDrawerList
.setAdapter(new ArrayAdapter<>(this, R.layout.drawer_list_item, testFragmentNames));
// Set the list's click listener
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.mipmap.ic_drawer, R.string.drawerOpen, R.string.drawerClose) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getSupportActionBar().setTitle(testFragmentNames.get(selectedFragmentIndex));
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getSupportActionBar().setTitle(R.string.app_name);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// Set MainTestFragment
selectItem(0);
new CedarMapsAuthenticateTask().execute();
onNavigationItemSelected(navigationView.getMenu().getItem(0));
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@SuppressWarnings("StatementWithEmptyBody")
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectItem(position);
}
}
/**
* Swaps fragments in the main content view
*/
private void selectItem(int position) {
selectedFragmentIndex = position;
// Create a new fragment and specify the planet to show based on position
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
Fragment fragment;
switch (position) {
case 0:
switch (item.getItemId()) {
case R.id.mainTestMap:
fragment = new MainTestFragment();
break;
case 1:
case R.id.markersTestMap:
fragment = new MarkersTestFragment();
break;
case 2:
case R.id.itemizedOverlayTestMap:
fragment = new ItemizedIconOverlayTestFragment();
break;
case 3:
case R.id.searchAPI:
fragment = new APIGeocodeTestFragment();
break;
case 4:
case R.id.streetSearchAPIAdvanced:
fragment = new APIAdvancedGeocodeTestFragment();
break;
case 5:
case R.id.reverseGeocode:
fragment = new APIReverseGeocodeTestFragment();
break;
default:
......@@ -173,15 +107,10 @@ public class MainActivity extends ActionBarActivity {
.replace(R.id.content_frame, fragment)
.commit();
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(testFragmentNames.get(position));
mDrawerLayout.closeDrawer(mDrawerList);
}
@Override
public void setTitle(CharSequence title) {
getSupportActionBar().setTitle(title);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
setTitle(item.getTitle());
return true;
}
class CedarMapsAuthenticateTask extends AsyncTask<Void, Void, Void> {
......
......@@ -5,7 +5,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
......@@ -23,52 +23,29 @@ import com.cedarstudios.cedarmaps.sample.R;
import com.cedarstudios.cedarmapssdk.CedarMaps;
import com.cedarstudios.cedarmapssdk.CedarMapsException;
import com.cedarstudios.cedarmapssdk.CedarMapsFactory;
import com.cedarstudios.cedarmapssdk.CedarMapsTileLayerListener;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapsTileLayer;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.overlay.Icon;
import com.mapbox.mapboxsdk.overlay.Marker;
import com.mapbox.mapboxsdk.views.MapView;
import org.json.JSONArray;
import org.json.JSONObject;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.overlay.Marker;
import java.util.ArrayList;
public class APIAdvancedGeocodeTestFragment extends Fragment implements View.OnClickListener {
public class APIAdvancedGeocodeTestFragment extends MainTestFragment implements View.OnClickListener {
private EditText mSearchEditText;
private MapView mapView;
private ArrayList<Marker> mMarkers = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_search, container, false);
mapView = (MapView) view.findViewById(R.id.mapView);
Configuration
configuration = new ConfigurationBuilder()
.setClientId(Constants.CLIENT_ID)
.setClientSecret(Constants.CLIENT_SECRET)
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_search, container, false);
}
final CedarMapsTileLayer cedarMapsTileLayer = new CedarMapsTileLayer(configuration);
cedarMapsTileLayer.setTileLayerListener(new CedarMapsTileLayerListener() {
@Override
public void onPrepared(CedarMapsTileLayer tileLayer) {
mapView.setTileSource(tileLayer);
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
}
});
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.search).setOnClickListener(this);
mSearchEditText = (EditText) view.findViewById(R.id.term);
......@@ -83,15 +60,12 @@ public class APIAdvancedGeocodeTestFragment extends Fragment implements View.OnC
return false;
}
});
return view;
}
@Override
public void onClick(View v) {
if (!TextUtils.isEmpty(mSearchEditText.getText().toString())) {
InputMethodManager inputManager = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
......@@ -102,14 +76,12 @@ public class APIAdvancedGeocodeTestFragment extends Fragment implements View.OnC
}
private void clearMarkers() {
for (Marker marker : mMarkers) {
mapView.removeMarker(marker);
}
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
mMapView.getOverlays().clear();
mMapView.invalidate();
mMapView.getController().setZoom(12);
mMapView.getController().animateTo(new GeoPoint(35.6961, 51.4231)); // center of tehran
mMarkers.clear();
mapView.clear();
}
class SearchAsyncTask extends AsyncTask<String, Void, JSONObject> {
......@@ -139,7 +111,7 @@ public class APIAdvancedGeocodeTestFragment extends Fragment implements View.OnC
.build();
CedarMaps cedarMaps = new CedarMapsFactory(configuration).getInstance();
LatLng location = new LatLng(35.6961, 51.4231);
GeoPoint location = new GeoPoint(35.6961, 51.4231);
searchResult = cedarMaps.geocode(params[0], location, 50, null, 5);
} catch (CedarMapsException e) {
e.printStackTrace();
......@@ -161,10 +133,11 @@ public class APIAdvancedGeocodeTestFragment extends Fragment implements View.OnC
for (int i = 0; i < array.length(); i++) {
JSONObject item = array.getJSONObject(i);
String[] location = item.getJSONObject("location").getString("center").split(",");
LatLng latLng = new LatLng(Double.parseDouble(location[0]), Double.parseDouble(location[1]));
Marker marker = new Marker(mapView, item.getString("name"), "", latLng);
marker.setIcon(new Icon(getActivity(), Icon.Size.MEDIUM, "marker-stroked", "FF0000"));
mapView.addMarker(marker);
GeoPoint latLng = new GeoPoint(Double.parseDouble(location[0]), Double.parseDouble(location[1]));
Marker marker = new Marker(mMapView);
marker.setPosition(latLng);
marker.setTitle(item.getString("name"));
mMapView.getOverlays().add(marker);
}
} else if (status.equals("ZERO_RESULTS")) {
Toast.makeText(getActivity(), getString(R.string.no_results), Toast.LENGTH_LONG).show();
......
......@@ -5,7 +5,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
......@@ -23,52 +23,30 @@ import com.cedarstudios.cedarmaps.sample.R;
import com.cedarstudios.cedarmapssdk.CedarMaps;
import com.cedarstudios.cedarmapssdk.CedarMapsException;
import com.cedarstudios.cedarmapssdk.CedarMapsFactory;
import com.cedarstudios.cedarmapssdk.CedarMapsTileLayerListener;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapsTileLayer;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.overlay.Icon;
import com.mapbox.mapboxsdk.overlay.Marker;
import com.mapbox.mapboxsdk.views.MapView;
import org.json.JSONArray;
import org.json.JSONObject;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.overlay.Marker;
import java.util.ArrayList;
public class APIGeocodeTestFragment extends Fragment implements View.OnClickListener {
public class APIGeocodeTestFragment extends MainTestFragment implements View.OnClickListener {
private EditText mSearchEditText;
private MapView mapView;
private ArrayList<Marker> mMarkers = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_search, container, false);
mapView = (MapView) view.findViewById(R.id.mapView);
Configuration
configuration = new ConfigurationBuilder()
.setClientId(Constants.CLIENT_ID)
.setClientSecret(Constants.CLIENT_SECRET)
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_search, container, false);
}
final CedarMapsTileLayer cedarMapsTileLayer = new CedarMapsTileLayer(configuration);
cedarMapsTileLayer.setTileLayerListener(new CedarMapsTileLayerListener() {
@Override
public void onPrepared(CedarMapsTileLayer tileLayer) {
mapView.setTileSource(tileLayer);
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
}
});
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.search).setOnClickListener(this);
mSearchEditText = (EditText) view.findViewById(R.id.term);
......@@ -83,15 +61,12 @@ public class APIGeocodeTestFragment extends Fragment implements View.OnClickList
return false;
}
});
return view;
}
@Override
public void onClick(View v) {
if (!TextUtils.isEmpty(mSearchEditText.getText().toString())) {
InputMethodManager inputManager = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
clearMarkers();
......@@ -101,14 +76,12 @@ public class APIGeocodeTestFragment extends Fragment implements View.OnClickList
}
private void clearMarkers() {
for (Marker marker : mMarkers) {
mapView.removeMarker(marker);
}
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
mMapView.getOverlays().clear();
mMapView.invalidate();
mMapView.getController().setZoom(12);
mMapView.getController().animateTo(new GeoPoint(35.6961, 51.4231)); // center of tehran
mMarkers.clear();
mapView.clear();
}
class SearchAsyncTask extends AsyncTask<String, Void, JSONObject> {
......@@ -158,28 +131,20 @@ public class APIGeocodeTestFragment extends Fragment implements View.OnClickList
JSONArray array = jsonObject.getJSONArray("results");
for (int i = 0; i < array.length(); i++) {
JSONObject item = array.getJSONObject(i);
String[] location = item.getJSONObject("location").getString("center")
.split(",");
LatLng latLng = new LatLng(Double.parseDouble(location[0]),
Double.parseDouble(location[1]));
Marker marker = new Marker(mapView, item.getString("name"), "", latLng);
marker.setIcon(
new Icon(getActivity(), Icon.Size.MEDIUM, "marker-stroked",
"FF0000"));
mapView.addMarker(marker);
String[] location = item.getJSONObject("location").getString("center").split(",");
GeoPoint latLng = new GeoPoint(Double.parseDouble(location[0]), Double.parseDouble(location[1]));
Marker marker = new Marker(mMapView);
marker.setPosition(latLng);
marker.setTitle(item.getString("name"));
mMapView.getOverlays().add(marker);
}
} else if (status.equals("ZERO_RESULTS")) {
Toast.makeText(getActivity(), getString(R.string.no_results),
Toast.LENGTH_LONG)
.show();
Toast.makeText(getActivity(), getString(R.string.no_results), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), getString(R.string.unkonown_error),
Toast.LENGTH_LONG)
.show();
Toast.makeText(getActivity(), getString(R.string.unkonown_error), Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getActivity(), getString(R.string.parse_error),
Toast.LENGTH_LONG).show();
Toast.makeText(getActivity(), getString(R.string.parse_error), Toast.LENGTH_LONG).show();
}
}
}
......
package com.cedarstudios.cedarmaps.sample.fragment;
import com.cedarstudios.cedarmaps.sample.Constants;
import com.cedarstudios.cedarmaps.sample.MainActivity;
import com.cedarstudios.cedarmaps.sample.R;
import com.cedarstudios.cedarmapssdk.CedarMaps;
import com.cedarstudios.cedarmapssdk.CedarMapsException;
import com.cedarstudios.cedarmapssdk.CedarMapsFactory;
import com.cedarstudios.cedarmapssdk.CedarMapsTileLayerListener;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapsTileLayer;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.overlay.Icon;
import com.mapbox.mapboxsdk.overlay.Marker;
import com.mapbox.mapboxsdk.views.MapView;
import org.json.JSONObject;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
......@@ -34,44 +17,39 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.cedarstudios.cedarmaps.sample.Constants;
import com.cedarstudios.cedarmaps.sample.MainActivity;
import com.cedarstudios.cedarmaps.sample.R;
import com.cedarstudios.cedarmapssdk.CedarMaps;
import com.cedarstudios.cedarmapssdk.CedarMapsException;
import com.cedarstudios.cedarmapssdk.CedarMapsFactory;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import org.json.JSONObject;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.overlay.Marker;
import java.util.ArrayList;
public class APIReverseGeocodeTestFragment extends Fragment implements View.OnClickListener {
public class APIReverseGeocodeTestFragment extends MainTestFragment implements View.OnClickListener {
private EditText mSearchEditText;
private MapView mapView;
private ArrayList<Marker> mMarkers = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_search, container, false);
mapView = (MapView) view.findViewById(R.id.mapView);
Configuration
configuration = new ConfigurationBuilder()
.setClientId(Constants.CLIENT_ID)
.setClientSecret(Constants.CLIENT_SECRET)
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_search, container, false);
}
final CedarMapsTileLayer cedarMapsTileLayer = new CedarMapsTileLayer(configuration);
cedarMapsTileLayer.setTileLayerListener(new CedarMapsTileLayerListener() {
@Override
public void onPrepared(CedarMapsTileLayer tileLayer) {
mapView.setTileSource(tileLayer);
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
}
});
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.search).setOnClickListener(this);
mSearchEditText = (EditText) view.findViewById(R.id.term);
mSearchEditText.setText("35.759926, 51.432512");
mSearchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
......@@ -83,17 +61,12 @@ public class APIReverseGeocodeTestFragment extends Fragment implements View.OnCl
return false;
}
});
mSearchEditText.setText("35.759926, 51.432512");
return view;
}
@Override
public void onClick(View v) {
if (!TextUtils.isEmpty(mSearchEditText.getText().toString())) {
InputMethodManager inputManager = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
......@@ -104,14 +77,12 @@ public class APIReverseGeocodeTestFragment extends Fragment implements View.OnCl
}
private void clearMarkers() {
for (Marker marker : mMarkers) {
mapView.removeMarker(marker);
}
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
mMapView.getOverlays().clear();
mMapView.invalidate();
mMapView.getController().setZoom(12);
mMapView.getController().animateTo(new GeoPoint(35.6961, 51.4231)); // center of tehran
mMarkers.clear();
mapView.clear();
}
class ReverseGeocodeAsyncTask extends AsyncTask<String, Void, JSONObject> {
......@@ -143,8 +114,7 @@ public class APIReverseGeocodeTestFragment extends Fragment implements View.OnCl
CedarMaps cedarMaps = new CedarMapsFactory(configuration).getInstance();
String[] latlng = params[0].split(",");
searchResult = cedarMaps.geocode(Double.parseDouble(latlng[0]),
Double.parseDouble(latlng[1]));
searchResult = cedarMaps.geocode(Double.parseDouble(latlng[0]), Double.parseDouble(latlng[1]));
} catch (CedarMapsException e) {
e.printStackTrace();
}
......@@ -161,33 +131,22 @@ public class APIReverseGeocodeTestFragment extends Fragment implements View.OnCl
try {
String status = jsonObject.getString("status");
if (status.equals("OK")) {
String address = jsonObject
.getJSONObject("result")
.getString("address");
String[] latlng = mSearchEditText.getText().toString().trim().split(",");
Marker marker = new Marker(mapView, address, "",
new LatLng(Double.parseDouble(latlng[0]),
Double.parseDouble(latlng[1])));
marker.setIcon(
new Icon(getActivity(), Icon.Size.MEDIUM, "marker-stroked",
"000FFF"));
mapView.addMarker(marker);
Toast.makeText(getActivity(), address,
Toast.LENGTH_LONG)
.show();
String address = jsonObject.getJSONObject("result").getString("address");
String[] location = mSearchEditText.getText().toString().trim().split(",");
GeoPoint latLng = new GeoPoint(Double.parseDouble(location[0]), Double.parseDouble(location[1]));
Marker marker = new Marker(mMapView);
marker.setPosition(latLng);
marker.setTitle(address);
mMapView.getOverlays().add(marker);
Toast.makeText(getActivity(), address, Toast.LENGTH_LONG).show();
} else if (status.equals("ZERO_RESULTS")) {
Toast.makeText(getActivity(), getString(R.string.no_results),
Toast.LENGTH_LONG)
.show();
Toast.makeText(getActivity(), getString(R.string.no_results), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), getString(R.string.unkonown_error),
Toast.LENGTH_LONG)
.show();
Toast.makeText(getActivity(), getString(R.string.unkonown_error), Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
Toast.makeText(getActivity(), getString(R.string.parse_error),
Toast.LENGTH_LONG).show();
Toast.makeText(getActivity(), getString(R.string.parse_error), Toast.LENGTH_LONG).show();
}
}
}
......
package com.cedarstudios.cedarmaps.sample.fragment;
import com.cedarstudios.cedarmaps.sample.Constants;
import com.cedarstudios.cedarmaps.sample.R;
import com.cedarstudios.cedarmapssdk.CedarMapsTileLayerListener;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapsTileLayer;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.overlay.ItemizedIconOverlay;
import com.mapbox.mapboxsdk.overlay.Marker;
import com.mapbox.mapboxsdk.views.MapView;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.util.ArrayList;
import com.cedarstudios.cedarmaps.sample.R;
public class ItemizedIconOverlayTestFragment extends Fragment {
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.ItemizedOverlay;
import org.osmdroid.views.overlay.OverlayItem;
import java.util.ArrayList;
public class ItemizedIconOverlayTestFragment extends MainTestFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map, container, false);
final MapView mapView = (MapView) view.findViewById(R.id.mapView);
Configuration
configuration = new ConfigurationBuilder()
.setClientId(Constants.CLIENT_ID)
.setClientSecret(Constants.CLIENT_SECRET)
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
final CedarMapsTileLayer cedarMapsTileLayer = new CedarMapsTileLayer(configuration);
cedarMapsTileLayer.setTileLayerListener(new CedarMapsTileLayerListener() {
protected void onMapLoaded() {
mMapView.getController().setZoom(15);
mMapView.getController().setCenter(new GeoPoint(35.762734, 51.432126));
final ArrayList<OverlayItem> items = new ArrayList<>();
items.add(new OverlayItem(getString(R.string.haghani_metro), "", new GeoPoint(35.759926, 51.432512)));
items.add(new OverlayItem(getString(R.string.third_street), "", new GeoPoint(35.762329, 51.429722)));
items.add(new OverlayItem(getString(R.string.haghani_way), "", new GeoPoint(35.759055, 51.427362)));
items.add(new OverlayItem(getString(R.string.tabrizian), "", new GeoPoint(35.762538, 51.435173)));
/* OnTapListener for the Markers, shows a simple Toast. */
ItemizedOverlay<OverlayItem> mMyLocationOverlay = new ItemizedIconOverlay<>(items,
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
@Override
public void onPrepared(CedarMapsTileLayer tileLayer) {
mapView.setTileSource(tileLayer);
mapView.setZoom(15);
mapView.setCenter(new LatLng(35.762734, 51.432126));
ArrayList<Marker> markers = new ArrayList<>();
markers.add(new Marker(mapView, getString(R.string.haghani_metro), "",
new LatLng(35.759926, 51.432512)));
markers.add(new Marker(mapView, getString(R.string.third_street), "",
new LatLng(35.762329, 51.429722)));
markers.add(new Marker(mapView, getString(R.string.haghani_way), "",
new LatLng(35.759055, 51.427362)));
markers.add(new Marker(mapView, getString(R.string.tabrizian), "",
new LatLng(35.762538, 51.435173)));
for (Marker marker : markers) {
marker.setMarker(getResources().getDrawable(R.drawable.ic_location_on));
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
Toast.makeText(getActivity(), "Item '" + item.getTitle() + "' (index=" + index
+ ") got single tapped up", Toast.LENGTH_LONG).show();
return true; // We 'handled' this event.
}
mapView.addItemizedOverlay(new ItemizedIconOverlay(getActivity(), markers,
new ItemizedIconOverlay.OnItemGestureListener<Marker>() {
@Override
public boolean onItemSingleTapUp(int i, Marker marker) {
Toast.makeText(getActivity(), marker.getTitle(), Toast.LENGTH_SHORT)
.show();
return true;
public boolean onItemLongPress(final int index, final OverlayItem item) {
Toast.makeText(getActivity(), "Item '" + item.getTitle() + "' (index=" + index
+ ") got long pressed", Toast.LENGTH_LONG).show();
return false;
}
}, getContext());
mMapView.getOverlays().add(mMyLocationOverlay);
@Override
public boolean onItemLongPress(int i, Marker marker) {
Toast.makeText(getActivity(), marker.getTitle(), Toast.LENGTH_LONG)
.show();
return true;
}
}));
}
});
return view;
}
}
package com.cedarstudios.cedarmaps.sample.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.cedarstudios.cedarmaps.sample.Constants;
import com.cedarstudios.cedarmaps.sample.MainActivity;
import com.cedarstudios.cedarmaps.sample.R;
import com.cedarstudios.cedarmapssdk.CedarMaps;
import com.cedarstudios.cedarmapssdk.CedarMapsTileLayerListener;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapsTileLayer;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.views.MapView;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapTileProvider;
import com.cedarstudios.cedarmapssdk.tileprovider.tilesource.CedarMapsTileSource;
import com.cedarstudios.cedarmapssdk.tileprovider.tilesource.CedarMapsTileSourceInfo;
import com.cedarstudios.cedarmapssdk.view.MapView;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.osmdroid.util.GeoPoint;
public class MainTestFragment extends Fragment {
protected MapView mMapView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map, container, false);
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_map, container, false);
}
final MapView mapView = (MapView) view.findViewById(R.id.mapView);
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mMapView = (MapView) view.findViewById(R.id.mapView);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Configuration
configuration = new ConfigurationBuilder()
......@@ -35,18 +46,32 @@ public class MainTestFragment extends Fragment {
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
final CedarMapsTileLayer cedarMapsTileLayer = new CedarMapsTileLayer(configuration);
cedarMapsTileLayer.setTileLayerListener(new CedarMapsTileLayerListener() {
final CedarMapsTileSourceInfo cedarMapsTileSourceInfo = new CedarMapsTileSourceInfo(getContext(), configuration);
cedarMapsTileSourceInfo.setTileLayerListener(new CedarMapsTileLayerListener() {
@Override
public void onPrepared(CedarMapsTileLayer tileLayer) {
mapView.setTileSource(tileLayer);
public void onPrepared(CedarMapsTileSourceInfo tileLayer) {
CedarMapsTileSource cedarMapsTileSource = new CedarMapsTileSource(tileLayer);
CedarMapTileProvider provider = new CedarMapTileProvider(getActivity().getApplicationContext(), cedarMapsTileSource);
mMapView.setTileProvider(provider);
mMapView.getController().setZoom(12);
mMapView.getController().setCenter(new GeoPoint(35.6961, 51.4231));
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
onMapLoaded();
}
});
}
@Override
public void onDetach() {
super.onDetach();
mMapView.onDetach();
mMapView = null;
}
protected void onMapLoaded() {
return view;
}
}
package com.cedarstudios.cedarmaps.sample.fragment;
import com.cedarstudios.cedarmaps.sample.Constants;
import com.cedarstudios.cedarmaps.sample.MainActivity;
import com.cedarstudios.cedarmaps.sample.R;
import com.cedarstudios.cedarmapssdk.CedarMapsTileLayerListener;
import com.cedarstudios.cedarmapssdk.config.Configuration;
import com.cedarstudios.cedarmapssdk.config.ConfigurationBuilder;
import com.cedarstudios.cedarmapssdk.tileprovider.CedarMapsTileLayer;
import com.mapbox.mapboxsdk.api.ILatLng;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.overlay.Icon;
import com.mapbox.mapboxsdk.overlay.Marker;
import com.mapbox.mapboxsdk.views.MapController;
import com.mapbox.mapboxsdk.views.MapView;
import com.mapbox.mapboxsdk.views.MapViewListener;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MarkersTestFragment extends Fragment implements MapViewListener {
import android.support.v4.content.ContextCompat;
private MapView mapView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map, container, false);
mapView = (MapView) view.findViewById(R.id.mapView);
import com.cedarstudios.cedarmaps.sample.R;
Configuration
configuration = new ConfigurationBuilder()
.setClientId(Constants.CLIENT_ID)
.setClientSecret(Constants.CLIENT_SECRET)
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.overlay.Marker;
final CedarMapsTileLayer cedarMapsTileLayer = new CedarMapsTileLayer(configuration);
cedarMapsTileLayer.setTileLayerListener(new CedarMapsTileLayerListener() {
public class MarkersTestFragment extends MainTestFragment {
@Override
public void onPrepared(CedarMapsTileLayer tileLayer) {
mapView.setTileSource(tileLayer);
protected void onMapLoaded() {
mapView.setZoom(14);
mapView.setCenter(new LatLng(35.703859, 51.408037));
mMapView.getController().setZoom(14);
mMapView.getController().setCenter(new GeoPoint(35.703859, 51.408037));
LatLng position = new LatLng(35.709086, 51.401471);
GeoPoint position = new GeoPoint(35.709086, 51.401471);
addMarker(position);
position = new LatLng(35.699781, 51.397565);
position = new GeoPoint(35.699781, 51.397565);
addMarker(position);
position = new LatLng(35.705636, 51.414174);
position = new GeoPoint(35.705636, 51.414174);
addMarker(position);
position = new LatLng(35.698631, 51.407693);
position = new GeoPoint(35.698631, 51.407693);
addMarker(position);
mapView.setMapViewListener(MarkersTestFragment.this);
}
});
return view;
}
public void addMarker(LatLng position) {
Marker marker = new Marker(mapView, "", "", position);
marker.setIcon(new Icon(getActivity(), Icon.Size.SMALL, "marker-stroked", "FF0000"));
mapView.addMarker(marker);
}
@Override
public void onShowMarker(MapView mapView, Marker marker) {
}
@Override
public void onHideMarker(MapView mapView, Marker marker) {
}
@Override
public void onTapMarker(MapView mapView, Marker marker) {
MapController mapController = new MapController(mapView);
mapController.animateTo(marker.getPoint());
}
@Override
public void onLongPressMarker(MapView mapView, Marker marker) {
}
@Override
public void onTapMap(MapView mapView, ILatLng iLatLng) {
}
@Override
public void onLongPressMap(MapView mapView, ILatLng iLatLng) {
private void addMarker(GeoPoint position) {
Marker marker = new Marker(mMapView);
marker.setIcon(ContextCompat.getDrawable(getContext(), R.drawable.marker_default));
marker.setPosition(position);
mMapView.getOverlays().add(marker);
}
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
<path
android:fillColor="#FF000000"
android:pathData="M9,2L7.17,4H4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2H9zm3,15c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M22,16V4c0,-1.1 -0.9,-2 -2,-2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zm-11,-4l2.03,2.71L16,11l4,5H8l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2H4V6H2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M22.7,19l-9.1,-9.1c0.9,-2.3 0.4,-5 -1.5,-6.9 -2,-2 -5,-2.4 -7.4,-1.3L9,6 6,9 1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1c1.9,1.9 4.6,2.4 6.9,1.5l9.1,9.1c0.4,0.4 1,0.4 1.4,0l2.3,-2.3c0.5,-0.4 0.5,-1.1 0.1,-1.4z"/>
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6zm16,-4H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zm-8,12.5v-9l6,4.5 -6,4.5z"/>
</vector>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:centerColor="#4CAF50"
android:endColor="#2E7D32"
android:startColor="#81C784"
android:type="linear"/>
</shape>
\ No newline at end of file
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- The navigation drawer -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="260dp"
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111" />
</android.support.v4.widget.DrawerLayout>
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.cedarstudios.cedarmaps.sample.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main"/>
</android.support.design.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="@+id/content_frame"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.cedarstudios.cedarmaps.sample.MainActivity"
tools:showIn="@layout/app_bar_main">
</FrameLayout>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:textColor="#fff"
android:background="#00000000"
android:minHeight="24dp"
android:textSize="20sp" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:layout_height="fill_parent"
android:orientation="vertical">
<com.mapbox.mapboxsdk.views.MapView
<com.cedarstudios.cedarmapssdk.view.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
android:layout_height="fill_parent"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/cedarmaps_attribution"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:padding="3dp"
android:layout_alignParentRight="true" />
android:src="@drawable/cedarmaps_attribution"/>
</RelativeLayout>
......@@ -39,7 +39,7 @@
</LinearLayout>
<com.mapbox.mapboxsdk.views.MapView
<com.cedarstudios.cedarmapssdk.view.MapView
android:id="@+id/mapView"
android:layout_width="fill_parent"
android:layout_height="0dp"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/mainTestMap"
android:title="@string/mainTestMap"/>
<item
android:id="@+id/markersTestMap"
android:title="@string/markersTestMap"/>
<item
android:id="@+id/itemizedOverlayTestMap"
android:title="@string/itemizedOverlayTestMap"/>
<item
android:id="@+id/searchAPI"
android:title="@string/searchAPI"/>
<item
android:id="@+id/streetSearchAPIAdvanced"
android:title="@string/streetSearchAPIAdvanced"/>
<item
android:id="@+id/reverseGeocode"
android:title="@string/reverseGeocode"/>
</group>
</menu>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="never" />
android:title="@string/action_settings"
app:showAsAction="never"/>
</menu>
<resources>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
......@@ -2,4 +2,12 @@
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="nav_header_vertical_spacing">16dp</dimen>
<dimen name="nav_header_height">160dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<!-- Per the design guidelines, navigation drawers should be between 240dp and 320dp:
https://developer.android.com/design/patterns/navigation-drawer.html -->
<dimen name="navigation_drawer_width">240dp</dimen>
</resources>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<item name="ic_menu_camera" type="drawable">@android:drawable/ic_menu_camera</item>
<item name="ic_menu_gallery" type="drawable">@android:drawable/ic_menu_gallery</item>
<item name="ic_menu_slideshow" type="drawable">@android:drawable/ic_menu_slideshow</item>
<item name="ic_menu_manage" type="drawable">@android:drawable/ic_menu_manage</item>
<item name="ic_menu_share" type="drawable">@android:drawable/ic_menu_share</item>
<item name="ic_menu_send" type="drawable">@android:drawable/ic_menu_send</item>
</resources>
......@@ -20,5 +20,13 @@
<string name="unkonown_error">خطایی پیش آمد</string>
<string name="no_results">نتیجه‌ای یافت نشد</string>
<string name="parse_error">خطای پردازش نتیجه</string>
<string name="title_activity_main">MainActivity</string>
<string name="title_section1">Section 1</string>
<string name="title_section2">Section 2</string>
<string name="title_section3">Section 3</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
</resources>
......@@ -5,4 +5,13 @@
<!-- Customize your theme here. -->
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
</resources>
......@@ -16,7 +16,7 @@ repositories {
}
dependencies {
compile('com.cedarmaps:CedarMapsSDK:0.7.4@aar') {
compile('com.cedarmaps:CedarMapsSDK:1.0.0@aar') {
transitive = true
}
}
......@@ -29,18 +29,22 @@ Ensure the following *core* permissions are requested in your `AndroidManifest.x
```xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
```
If your project needs to access location services, it'll also need the following permissions too:
If your App needs to access location services, it'll also need the following permissions too:
```xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
```
**Android 6.0+ devices require you have to check for "dangerous" permissions at runtime.**
CedarMaps requires the following dangerous permissions:
`WRITE_EXTERNAL_STORAGE`, `ACCESS_COARSE_LOCATION` and `ACCESS_FINE_LOCATION`.
### Getting Access Token
In order to use CedarMaps API and TileSource you should get `AccessToken` with your client id and
......@@ -62,9 +66,6 @@ Then you should use `oAuth2Token.getAccessToken()` in mapView or API
### The MapView
This project is based on [Mapbox Android SDK](https://www.mapbox.com/mapbox-android-sdk/) and provides
CedarMapsTileLayer and extra API over Mapbox.
The `MapView` class is the key component of this library. It behaves
like any other `ViewGroup` and its behavior can be changed statically with an
[XML layout](http://developer.android.com/guide/topics/ui/declaring-layout.html)
......@@ -74,7 +75,7 @@ file, or programmatically during runtime.
To add the `MapView` as a layout element, add the following to your xml file:
```xml
<com.mapbox.mapboxsdk.views.MapView
<com.cedarstudios.cedarmapssdk.view.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
......@@ -85,33 +86,21 @@ And then you can call it programmatically with
```java
MapView mapView = (MapView) findViewById(R.id.mapview);
```
#### On runtime
final CedarMapsTileSourceInfo cedarMapsTileSourceInfo = new CedarMapsTileSourceInfo(getContext(), configuration);
cedarMapsTileSourceInfo.setTileLayerListener(new CedarMapsTileLayerListener() {
@Override
public void onPrepared(CedarMapsTileSourceInfo tileLayer) {
On runtime you can create a new MapView by specifying the context of the
application and then use `CedarMapsTileLayer` as tile source.
CedarMapsTileSource cedarMapsTileSource = new CedarMapsTileSource(tileLayer);
CedarMapTileProvider provider = new CedarMapTileProvider(getContext(), cedarMapsTileSource);
mapView.setTileProvider(provider);
mapView.getController().setZoom(12);
mapView.getController().setCenter(new GeoPoint(35.6961, 51.4231)); // center of Tehran
```java
MapView mapView = new MapView(context);
Configuration configuration = new ConfigurationBuilder()
.setClientId(Constants.CLIENT_ID)
.setClientSecret(Constants.CLIENT_SECRET)
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
final CedarMapsTileLayer cedarMapsTileLayer = new CedarMapsTileLayer(configuration);
cedarMapsTileLayer.setTileLayerListener(new CedarMapsTileLayerListener() {
@Override
public void onPrepared(CedarMapsTileLayer tileLayer) {
mapView.setTileSource(tileLayer);
mapView.setZoom(12);
mapView.setCenter(new LatLng(35.6961, 51.4231)); // center of tehran
}
});
```
Currently you can use `cedarmaps.streets` as default mapId
#### Changing API Base Url
You can change API Base Url by setting it on configuration object:
......@@ -125,90 +114,13 @@ Configuration configuration = new ConfigurationBuilder()
.setMapId(Constants.MAPID_CEDARMAPS_STREETS)
.build();
```
CedarMaps SDK is based on [OpenStreetMap Android SDK v5.2](https://github.com/osmdroid/osmdroid) and provides `CedarMapsTileSource` and extra API over OpenStreetMap.
For more information about how to use MapView and other components please see [OpenStreetMap Wiki](https://github.com/osmdroid/osmdroid/wiki)
### Attention
currently CedarMaps supports Tehran city. so be sure that you handle the map screen limit by the
boundingBox and the default map center location:
```java
// center of tehran
mapView.setCenter(new LatLng(35.6961, 51.4231));
// limit scrollable area
mapView.setScrollableAreaLimit(new BoundingBox(north, east, south, west));
```
### Overlays
Anything visual that is displayed over the map, maintaining its geographical
position, we call it an `Overlay`. To access a MapView's overlays
at any point during runtime, use:
```java
mapView.getOverlays();
```
#### Markers
Adding a marker with the default styling is as simple as calling this
for every marker you want to add:
```java
Marker marker = new Marker(mapView, title, description, LatLng)
mapView.addMarker(marker);
```
#### Location overlay
The location of the user can be displayed on the view using `UserLocationOverlay`
```java
GpsLocationProvider myLocationProvider = new GpsLocationProvider(getActivity());
UserLocationOverlay myLocationOverlay = new UserLocationOverlay(myLocationProvider, mapView);
myLocationOverlay.enableMyLocation();
myLocationOverlay.setDrawAccuracyEnabled(true);
mapView.getOverlays().add(myLocationOverlay);
```
#### Paths
Paths are treated as any other `Overlay`, and are drawn like this:
```java
PathOverlay line = new PathOverlay(Color.RED, this);
line.addPoint(new LatLng(51.2, 0.1));
line.addPoint(new LatLng(51.7, 0.3));
mapView.getOverlays().add(line);
```
#### Drawing anything into the map
To add anything with a higher degree of customization you can declare your own `Overlay`
subclass and define what to draw by overriding the `draw` method. It will
give you a Canvas object for you to add anything to it:
```java
class AnyOverlay extends Overlay{
@Override
protected void draw(Canvas canvas, MapView mapView, boolean shadow) {
//do anything with the Canvas object
}
}
```
### Screen rotation
By default, every time the screen is rotated, Android will call `onCreate`
and return all states in the app to their inital values. This includes current
zoom level and position of the MapView. The simplest way to avoid this is adding
this line to your `AndroidManifest.xml`, inside `<activity>`:
android:configChanges="orientation|screenSize|uiMode"
currently CedarMaps supports Tehran city.
Alternatively you can override the methods `onSaveInstanceState()` and
`onRestoreInstanceState()` to have broader control of the saved states in the app.
See this [StackOverflow question](http://stackoverflow.com/questions/4096169/onsaveinstancestate-and-onrestoreinstancestate) for
more information on these methods
=======
### CedarMaps API
......@@ -515,6 +427,6 @@ the **TestApp**. It contains many different examples of new functionality or ju
The source code for these tests / examples is located under the CedarMapsTestApp directory.
You can find more useful examples on [Mapbox SDK Test App](https://github.com/mapbox/mapbox-android-sdk/tree/mb-pages/MapboxAndroidSDKTestApp)
You can find more useful examples on [OpenStreetMap SDK Test App](https://github.com/osmdroid/osmdroid)
......@@ -5,8 +5,8 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
classpath 'com.android.tools.build:gradle:2.2.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
......
#Wed Apr 10 15:27:10 PDT 2013
#Tue Aug 23 18:48:06 IRDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
include ':CedarMapsTestApp', ':CedarMapsSDK'
rootProject.name = 'artifact'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment