I'm trying to load a tile source, but for some reason it doenst work.
Here's my code:
final IRegisterReceiver registerReceiver = new SimpleRegisterReceiver(this);
// Create a custom tile source
final ITileSource tileSource = TileSourceFactory.MAPNIK;
// Create a file cache modular provider
final TileWriter tileWriter = new TileWriter();
final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(registerReceiver, tileSource);
File myMapTileSource = new File(mapsDirectory.getPath()+File.separator+"Lisboa.gemf");
// Create an archive file modular tile provider
IArchiveFile[] archives = { ArchiveFileFactory.getArchiveFile(myMapTileSource) };
MapTileFileArchiveProvider fileArchiveProvider = new MapTileFileArchiveProvider(registerReceiver, tileSource, archives);
// Create a download modular tile provider
final NetworkAvailabliltyCheck networkAvailablilityCheck = new NetworkAvailabliltyCheck(this);
final MapTileDownloader downloaderProvider = new MapTileDownloader(tileSource, tileWriter, networkAvailablilityCheck);
// Create a custom tile provider array with the custom tile source and the custom tile providers
final MapTileProviderArray tileProviderArray = new MapTileProviderArray(tileSource, registerReceiver, new MapTileModuleProviderBase[] { fileSystemProvider, fileArchiveProvider, downloaderProvider });
// Create the mapview with the custom tile provider array
mMapView = new MapView(this, 256, new DefaultResourceProxyImpl(this), tileProviderArray);
mMapView.setUseDataConnection(false);
For some reason this works and i can see the map of lisbon offline.
if i switch the line
File myMapTileSource = new File(mapsDirectory.getPath()+File.separator+"Lisboa.gemf");
for
File myMapTileSource = new File(mapsDirectory.getPath()+File.separator+"Lissabon.osm");
it doenst work. It returns an error "Error loading tile" from MapTileFileArchiveProvider.
The gemf file was created in MOBAC. The osm file was downloaded from here.
Could anyone explain me why it doenst work?
If you take a look at ArchiveFileFactory, you'll see that GEMF files are supported, but .osm files are not. I'm not sure what format .osm files are (maybe it's one of the supported formats and just needs to be renamed?)
Related
Part of my application involves fetching a random word from a list of words I have in a text file, "wordlist.txt". I'm trying to use Scanner to get my activity to interact with it and put the words into a java ArrayList, but Scanner does not detect the file I'm directing it to, giving me an Unhandled Exception:java.io.FileNotFoundException. What am I doing wrong? The relevant part of my code is below:
File wordList = new File("app\\src\\main\\res\\wordlist.txt"); // generate reference to file
final ArrayList<String> Dictionary = new ArrayList(); //create arraylist
final Scanner checker = new Scanner(wordList);
while (checker.hasNextLine()) {
final String data = checker.nextLine();
Dictionary.add(data);
}
checker.close();
I am trying to dynamically create an image database using arcores new image tracking feature.
Currently I have a server serving me image locations which I download to the persistent data path of my device. I use these images to then create new database entries like below:
Public Variables:
public AugmentedImageDatabase newBD;
public AugmentedImageDatabaseEntry newEntry;
Here I do regex matching to get the images from the datapath and convert them to texture2D's in order to populate the AugmentedImageDatabaseEntry values.
Regex r1 = new Regex(#"https?://s3-([^.]+).amazonaws.com/([^/]+)/([^/]+)/(.*)");
// Match the input for file name
Match match = r1.Match(input);
if (match.Success)
{
string v = match.Groups[4].Value;
RegexMatch = v;
Texture2D laodedTexture = LoadTextureToFile(v);
laodedTexture.EncodeToPNG();
AugmentedImageDatabaseEntry newEntry = new AugmentedImageDatabaseEntry(v, laodedTexture, Application.persistentDataPath + "/" + v);
newEntry.Name = v;
newEntry.Texture = laodedTexture;
newEntry.TextureGUID = Application.persistentDataPath + "/" + v;
Debug.Log(newEntry.Name);
Debug.Log(newEntry.Texture);
Debug.Log(newEntry.TextureGUID);
newBD.Add(newEntry);
}
To get this to work on android I had to modify the source of ARCore's unity implementation a little so that the database.Add() function would work outside of the editor.
All of this seems to work seamlessly as I don't get any errors yet.
Once I change scenes to the ARCore scene I instantiate an ARCore Camera and create a new sessionconfig which holds a reference to the database populated above.
Here is that code:
public class NewConfigSetup : MonoBehaviour {
public GameObject downloadManager;
public GameObject arcoreDevice;
// Use this for initialization
void Start () {
downloadManager = GameObject.Find("DownlaodManager");
TestModelGenerator generator = downloadManager.GetComponent<TestModelGenerator>();
GoogleARCore.ARCoreSessionConfig newconfig = new GoogleARCore.ARCoreSessionConfig();
GoogleARCore.ARCoreSessionConfig config = ScriptableObject.CreateInstance<GoogleARCore.ARCoreSessionConfig>();
config.AugmentedImageDatabase = generator.newBD;
Debug.Log("transfered db size --------------- " + config.AugmentedImageDatabase.Count);
arcoreDevice.GetComponent<GoogleARCore.ARCoreSession>().SessionConfig = config;
Instantiate(arcoreDevice,new Vector3(0,0,0), Quaternion.identity);
}
}
When I run in the editor, I dont get errors untill I view the database in the editor, thats when I get this error:
ERROR: flag '--input_image_path' is missing its argument; flag
description: Path of image to be evaluated. Currently only supports
*.png, *.jpg and *.jpeg.
When I debug and look in the memory of the AugmentedImageDatabase. Everything seems to be there and working fine. Also once I build for android I get no errors whatsoever, as well as when I use 'adb logcat -s Unity' in the command line, no exceptions are thrown.
Could this be a limitation with the new ARCore feature? Are the AugmentedImageDatabases not allowing for dynamic creation on android? If so than why are there built in functions for creating them?
I understand the features are brand new and there is not much documentation anywhere so any help would be greatly appreciated.
I posted an Issue on ARCore's Github page, and got a response that the feature you're talking about isn't yet exposed in the Unity API :
https://github.com/google-ar/arcore-unity-sdk/issues/256
I have developed a SDK for android applications.We have many clients using this SDK in there applications.Now i have updated my SDK.I am looking for a way that these changes can reflect in there application without updating there app on play store.Urgent help needed.Any help will be appreciated.Thanks in advance.
Well you can dynamically load a jar file from your SD card using DexLoader class...which you can update when ever you want..on your storage... below is working code..
final String libPath = Environment.getExternalStorageDirectory() + "/test.jar";
final File tmpDir = getDir("dex", 0);
final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("com.test.android.MainActivity");
final Object myInstance = classToLoad.newInstance();
final Method doSomething = classToLoad.getMethod("doSomething");
doSomething.invoke(myInstance);
and in your library file code can be like this
public class MainActivity {
public void doSomething() {
Log.e(MainActivity .class.getName(), "MainActivity : doSomething() called.");
}}
tell me if you need any assistance
there is no such way for your situation. But there is one thing you can do to enable it for next update. Android can dynamically load compiled code with DexClassLoader. So you compile a new DEX file, and then force your SDK to download and use it.
// Internal storage where the DexClassLoader writes the optimized dex file to
final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(),
null,
getClassLoader());
Class libProviderClazz = null;
try {
// Load the library.
libProviderClazz =
cl.loadClass("com.example.dex.lib.LibraryProvider");
// Cast the return object to the library interface so that the
// caller can directly invoke methods in the interface.
// Alternatively, the caller can invoke methods through reflection,
// which is more verbose.
LibraryInterface lib = (LibraryInterface) libProviderClazz.newInstance();
lib.showAwesomeToast(this, "hello");
} catch (Exception e) { ... }
I've been pulling my hair out trying to get my own offline Mobile Atlas Creator OSMDroid SQLite map working with OSMDroid 3.0.8 without luck. It's been a long 3 days. I'll try to explain with clips from my application. I've been extending ItemizedIconOverlay and OverlayItem so I hope it doesn't get too confusing.
I created my own OSMDroid SQLite map file with 3 different zoom levels for a small are, like 10 square kms. I copied the resulting "base.sqlite" file into my project /res/raw/ directory. Note that the GeoPoints in my application should be well within the map's tile range. The "base.sqlite" file should get saved to the application specific data directory.
Next I turfed the /osmdroid directory on my phone so I could get the previously cached maps off. I thought I had my own offline maps working until I turned on Airplane mode and noticed the cached maps were still available.
Now all I get is blanks. I have no clue how to get this going. I've see a couple of examples but after a ton of experimentation I haven't been successful in getting any of them working.
private Hashtable<String, NodeOverlayItem> nodes = new Hashtable<String, NodeOverlayItem>();
private MapView mapView;
private Context context;
private LocationManager locManager;
private MapController mapController;
private MapTileProviderArray mapProvider;
private String mapTileArchivePath = "base.sqlite";
private ResourceProxy resourceProxy;
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
this.mapView = new MapView(this, 256);
this.mapView.setBuiltInZoomControls(true);
this.mapView.setMultiTouchControls(true);
this.context = this.getApplicationContext();
this.resourceProxy = new DefaultResourceProxyImpl(context);
XYTileSource TILERENDERER = new XYTileSource("test",
ResourceProxy.string.offline_mode,
1, 20, 256, ".png", "http://127.0.0.1");
SimpleRegisterReceiver simpleReceiver = new SimpleRegisterReceiver(this.context);
IArchiveFile[] archives = { ArchiveFileFactory.getArchiveFile(this.getMapsFile()) };
MapTileModuleProviderBase moduleProvider = new MapTileFileArchiveProvider(
simpleReceiver,
TILERENDERER,
archives);
this.mapProvider = new MapTileProviderArray(TILERENDERER, null, new MapTileModuleProviderBase[] { moduleProvider });
this.mapProvider.setUseDataConnection(false);
this.mapView = new MapView(this, 256, this.resourceProxy, this.mapProvider);
this.mapView.setUseDataConnection(false);
mapController = mapView.getController();
mapController.setZoom(18);
mapController.setCenter(new GeoPoint((int)(45.349622 * 1E6), (int)(-75.880700 *1E6)));
this.setContentView(mapView);
} catch(Exception ex) {
Log.e("test", ex.getMessage());
}
}
public File getMapsFile() throws IOException {
Log.d("test", "Trying to load map tiles to: " + this.mapTileArchivePath);
FileOutputStream fos = this.openFileOutput(this.mapTileArchivePath, Context.MODE_PRIVATE);
InputStream in = getResources().openRawResource(R.raw.osmdroid);
byte[] buff = new byte[1024];
int read = 0;
try {
while ((read = in.read(buff)) > 0) {
fos.write(buff, 0, read);
}
} finally {
in.close();
fos.close();
}
return new File(this.getFilesDir(), this.mapTileArchivePath);
}
OK! I know what I doing wrong and I have it all working now! (I'm excited :)
Firstly, I had some trouble with writing my Raw resource map file to the application specific directory (e.g. openFileOutput()) I'm using a Galaxy Nexus which doesn't have an SD slot so I can't dump the map file to SD. Ensure the maps file you intend to use is byte compared with the original copy. Eclipse's DDMS perspective is useful to view a device's file structure.
I also switched to the OSMdroid Zip format. I then made sure the XYTileSource() name matched the directory created in the Zip file by MOBAC, plus ensure the tile size and zoom levels match.
XYTileSource TILERENDERER = new XYTileSource("OSM CloudMade 1", ResourceProxy.string.offline_mode, 16, 18, 256, ".png", "http://127.0.0.1");
MOBAC by default will create 256 pixel tiles. I created an atlas file with 16, 17, and 18 zoom levels. PNG is the default MOBAC tile image format.
Also, if your map file has any issues, ArchiveFileFactory.getArchiveFile() will catch them, even before MapTileFileArchiveProvider.
Here's my usage. Just make every effort to get your IArchive setup correctly and you should be ok:
XYTileSource TILERENDERER = new XYTileSource("OSM CloudMade 1", ResourceProxy.string.offline_mode, 16, 18, 256, ".png", "http://127.0.0.1");
SimpleRegisterReceiver simpleReceiver = new SimpleRegisterReceiver(this.context);
IArchiveFile[] archives = { ArchiveFileFactory.getArchiveFile(this.getMapsSdCard()) };
MapTileModuleProviderBase moduleProvider = new MapTileFileArchiveProvider(
simpleReceiver,
TILERENDERER,
archives);
this.mapProvider = new MapTileProviderArray(TILERENDERER, null, new MapTileModuleProviderBase[] { moduleProvider });
this.mapProvider.setUseDataConnection(false);
this.mapView = new MapView(this, 256, this.resourceProxy, this.mapProvider);
this.mapView.setUseDataConnection(false);
Maybe I'm the only one who had trouble with this, but osmdroid doesn't clearly document how to do this, and when I opened the issue I couldn't get them to comment on my usage. If they had said I was implementing MapTileFileArchiveProvider correctly or included a good offline mapping sample, I would have focused on everything else first.
If you want to use sqlite db you only have to change
ArchiveFileFactory.getArchiveFile(this.getMapsSdCard())
to
MBTilesFileArchive.getDatabaseFileArchive(f)
where f is a File that points to your sqlite database.
I want to create application to show offline map using GIS shape file(.shp) any one have idea that how to use shape file to display map in android.
Thanks in advance
If you are loading data from SD card, you can work with openmap it has a class SHapefile and try to transform your shapefile to an graphicslayer it will work i've already done it.
static public GraphicsLayer SHPtoPOINT(String shpfile) {
SpatialReference lSR = SpatialReference.create(26192);
Envelope lEnvolope = getSHPEnvelope(shpfile);//to create an extent for your graphics layer
GraphicsLayer graphicLayer = new GraphicsLayer(lSR, lEnvolope);
try {
File file = new File(shpfile);
ShapeFile shp = new ShapeFile(file);
ESRIPointRecord e = (ESRIPointRecord) shp.getNextRecord();
SimpleMarkerSymbol c_point = new SimpleMarkerSymbol(Color.BLACK, 1,
STYLE.CIRCLE);
while (e != null) {
graphicLayer.addGraphic(new Graphic(new Point(e.getX(), e.getY()), c_point));
e = (ESRIPointRecord) shp.getNextRecord();
}
shp.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return graphicLayer;
}
Source
EDIT:
BBN Technologies' OpenMap TM package is an Open Source JavaBeans TM
based programmer's toolkit. Using OpenMap, you can quickly build
applications and applets that access data from legacy databases and
applications. OpenMap provides the means to allow users to see and
manipulate geospatial information.
Link to OpenMap info.