Why osmdroid not working in offline mode (multiple questions)? - java

I am working on the OSMdroid library, and wanted to make it offline so i used this code
mMapView.setUseDataConnection(false);
but in this condition it won't even display the map other than the graph page. But when i change the boolean to true it again starts working.
So how do i make it work completely offline?
I am also trying to get the poi so i have the following code
geoPoint= new GeoPoint(37.439974,-119.003906);
double north = 84;
double east = -180;
double south = -84;
double west = 180;
boundingBoxE6 = new BoundingBoxE6(north, east, south, west);
mMapView.setScrollableAreaLimit(boundingBoxE6);
mMapView.setMultiTouchControls(true);
Marker marker= new Marker(mMapView,mResourceProxy);
marker.setPosition(geoPoint);
mMapView.getOverlays().add(marker);
poiMarkers = new FolderOverlay(getActivity());
new connection().execute();
mMapView.invalidate();
public class connection extends AsyncTask{
#Override
protected Object doInBackground(Object[] objects) {
NominatimPOIProvider poiProvider = new NominatimPOIProvider();
pois=poiProvider.getPOICloseTo(geoPoint,"atm",50,1000);
return pois;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
mMapView.getOverlays().add(poiMarkers);
Drawable poiIcon = getResources().getDrawable(R.drawable.marker_poi_default);
if (o != null) {
for (POI poi : pois) {
Marker poiMarker = new Marker(mMapView);
poiMarker.setTitle(poi.mType);
poiMarker.setSnippet(poi.mDescription);
poiMarker.setPosition(poi.mLocation);
poiMarker.setIcon(poiIcon);
poiMarkers.add(poiMarker);
}
}else{
Toast.makeText(getActivity(),"null",Toast.LENGTH_SHORT).show();
}
}
}
But instead of getting the poi on the given geopint i get it somewhere else and everytime i mean whatever the code i change i don't get the poi in any other places other than that
http://nominatim.openstreetmap.org/search?format=json&q=[atm]&limit=50&bounded=1&viewbox=-1119.003906,1037.439974,880.996094,-962.560026
Is it possible to access poi in offline mode?

As for the offline tiles showing, are you sure you have the offline map tiles .ZIP-file stored in /mnt/sdcard/osmdroid/ (or whatever the path for your device's SDcard is, it just has to be within this folder in a subdirectory called osmdroid)?
A good tutorial that helped me can be found here: http://www.haakseth.com/?p=30
The OSMdroid TileSource will automatically look for this .ZIP-file if there is no internet connection to retrieve the tiles from. In the OpenStreetMapTileProviderConstants class there is this piece of code:
/** Base path for osmdroid files. Zip files are in this folder. */
public static final File OSMDROID_PATH = new File(Environment.getExternalStorageDirectory(),
"osmdroid");
So as you can see, you just need to have the osmdroid-directory in your SDcard folder, and everything should work just fine.
If you don't have a map tiles .ZIP yet, check out Mobile Atlas Creator for creating this.

Related

Download CSV through HtmlUnit and read into array

I have a page that has a button to download information in the format of a CSV file. The button opens a confirm dialog to download the file. I need to store that file to a temporary location (whether that be memory or saving to an actual file and then deleting it after) and then read the data in the CSV to an array.
I've tried the code in these questions (question 1, question 2, question 3, and question 4), and it's not quite what I need - mostly because they weren't downloading a CSV and using the data in it.
I'm not sure that the ConfirmDialog is being opened, but I did add a ConfirmHandler returning true to attempt to download the file. However, I don't know where the file is downloading if it is at all.
Here's what I have happening and where I get stuck:
I log in just fine. I go to a report generator. I generate a report that opens in a new window. The new window opens fine and I catch it with a WebWindowListener. I then search for the "save as CSV" button on the new window. I can find that, and I can click on it, but a System.out.print call shows that the ConfirmHandler isn't firing.
for (DomElement e : newPage.getElementsByTagName("button")) {
int i = 0;
webClient.setConfirmHandler(new ConfirmHandler() {
private static final long serialVersionUID = 1L;
#Override
public boolean handleConfirm(Page arg0, String arg1) {
System.out.println("Test"); //isn't firing
return false;
}
});
if (((HtmlButton) e).getAttribute("onclick").contains("CSV")) {
((HtmlButton) e).click();
}else {
if (i++ == (newPage.getElementsByTagName("button").size() - 1)) throw new AssertionError("CSV button not found");
}
}
The inspiration for this answer came from this answer.
I really wanted to get the CSV information without downloading the file, and so I, inside of the webWindowContentChanged(arg0) method of my webWindowListener, just used arg0.getWebWindow().getEnclosingPage().getWebResponse().getContentAsString() and then used String.split() a couple times to get the information I wanted.
Here's what the code looks like so it's a little clearer:
webClient.addWebWindowListener(new WebWindowListener() {
#Override
public void webWindowContentChanged(WebWindowEvent arg0) {
if (CSVclicked) { //boolean that is set true when I click the download button...
String CSV = arg0.getWebWindow().getEnclosedPage().getWebResponse().getContentAsString();
//do things...
CSVclicked = false; //don't use the same behavior next time the method is called...
}
}
});

How to remove a symbol from a map

I am currently creating a map which updates based on users selection and displays 5 location closest to them. This works however when the user changes their selection the map updates and displays the 5 NEW locations as well as the 5 OLD locations.
I am not sure how to remove the old symbols.
public void displayResults(ArrayList allLocation) {
SymbolManager sm = new SymbolManager(mapView,map,styleMap);
sm.deleteAll();
SymList.clear();
sm.setIconAllowOverlap(true);
sm.setIconIgnorePlacement(true);
int count = 1;
for (LocationDetails a : allLocation
) {
// gets the distance from user to Location
double LocationLat = Double.parseDouble(a.getLatitude());
double LocationLng = Double.parseDouble(a.getLongitude());
float[] disResult = new float[1];
Location.distanceBetween(lat, lng, LocationLat, LocationLng, disResult);
results.append(count + ": " + a.getName() + " " + "\n");
distanceResults.append(Math.round(disResult[0]) + "m" + "\n");
SymbolOptions symbolOptions = new SymbolOptions()
.withLatLng(new LatLng(LocationLat, LocationLng))
.withIconImage("marker-11")
.withTextField(""+count)
.withIconColor("black")
.withIconSize(2.5f);
SymList.add(symbolOptions);
count++;
}
LatLngBounds latLngBounds = new LatLngBounds.Builder()
.include(SymList.get(0).getLatLng())
.include(SymList.get(1).getLatLng())
.include(SymList.get(2).getLatLng())
.include(SymList.get(3).getLatLng())
.include(SymList.get(4).getLatLng())
.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 50), 2000);
for(SymbolOptions a : SymList){
sm.create(a);
}
SymList.clear();
}
I have been using mapbox for 3 months. After hours of research I discovered that on Android the only way to remove a Symbol or any element on the map was to reload all the elements from scratch. Unfortunately, there is currently no method to remove a single element.
So I suggest you create a container class in which to save your items.
If your use case only requires showing about five markers on the map at a time, it might be easier to use native sources and SymbolLayers rather than relying on the abstraction provided by the SymbolManager.
For example, this icon updates based on API response Android demo shows how to add a GeoJSON source and corresponding layer to the map, then update said source to get a different visual result. Basically all of the logic you will need is encapsulated here, but your GeoJSON will be a FeatureCollection of multiple (namely, 5) features rather than just one point.
So, you can set up your symbols similarly to how it's done in the linked example:
private void initSpaceStationSymbolLayer(#NonNull Style style) {
style.addImage("space-station-icon-id",
BitmapFactory.decodeResource(
this.getResources(), R.drawable.iss));
style.addSource(new GeoJsonSource("source-id"));
style.addLayer(new SymbolLayer("layer-id", "source-id").withProperties(
iconImage("space-station-icon-id"),
iconIgnorePlacement(true),
iconAllowOverlap(true),
iconSize(.7f)
));
}
, and then update the source's GeoJSON to the new locations closest to the user's position, similar to the updateMarkerPostion method:
private void updateMarkerPosition(LatLng position) {
// This method is where we update the marker position once we have new coordinates. First we
// check if this is the first time we are executing this handler, the best way to do this is
// check if marker is null;
if (map.getStyle() != null) {
GeoJsonSource spaceStationSource = map.getStyle().getSourceAs("source-id");
if (spaceStationSource != null) {
spaceStationSource.setGeoJson(FeatureCollection.fromFeature(
Feature.fromGeometry(Point.fromLngLat(position.getLongitude(), position.getLatitude()))));
}
}
// Lastly, animate the camera to the new position so the user
// wont have to search for the marker and then return.
map.animateCamera(CameraUpdateFactory.newLatLng(position));
}
A few modifications will need to be made, of course, but this option might be more direct for your implementation specifically.

Why do dynamically added symbols show up grey in Mapbox

When I tap the screen, a marker gets added to the middle of a Mapbox map. The first marker shows up as it is supposed to. However as soon as I add a second marker, the markers show up grey.
Here is the code I use to create the symbol source and the symbol layer, as well as the onMapClickListener where the features of the symbol source get updated with the new marker. All this code is in the onStyleLoaded method.
//Create the symbol source
Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_map_marker_blue, null);
Bitmap marker = BitmapUtils.getBitmapFromDrawable(drawable);
style.addImage(BLUE_MARKER_IMAGE, marker);
GeoJsonSource geoJsonSourceSymbol = new GeoJsonSource(SYMBOL_SOURCE_ID);
style.addSource(geoJsonSourceSymbol);
//Create the symbol layer
symbolLayer = new SymbolLayer(SYMBOL_LAYER_ID, SYMBOL_SOURCE_ID);
symbolLayer.setProperties(iconImage(BLUE_MARKER_IMAGE), iconOffset(new Float[] {0f, -10f}));
style.addLayer(symbolLayer);
mapboxMap.addOnMapClickListener(new MapboxMap.OnMapClickListener() {
#Override
public boolean onMapClick(#NonNull LatLng point) {
final LatLng mapTargetLatLng = mapboxMap.getCameraPosition().target;
Point mapTarget = Point.fromLngLat(mapTargetLatLng.getLongitude(),mapTargetLatLng.getLatitude());
pointList.add(mapTarget);
featureList.add(Feature.fromGeometry(mapTarget));
if (style.getLayer(SYMBOL_LAYER_ID) != null) {
GeoJsonSource geoJsonSourceSymbol = style.getSourceAs(SYMBOL_SOURCE_ID);
if (geoJsonSourceSymbol != null) {
geoJsonSourceSymbol.setGeoJson(FeatureCollection.fromFeatures(featureList));
}
}
return true;
}
});
Is there something I'm doing wrong or is it not possible to dynamically add symbols using data-driven styling?
Are you using an emulator? The Mapbox team already knows of SymbolLayer rendering issues on emulated devices:
https://github.com/mapbox/mapbox-gl-native/issues/10829
https://github.com/mapbox/mapbox-plugins-android/issues/1082

Mark on PDF Android App

I'm currently developing an application on Android with AndroidPDFViewer : https://github.com/barteksc/AndroidPdfViewer
I want to create a functionality, when the user touch the screen, it put a point on the PDF at this location. After I want to measure the distance between 2 points but it's an other problem.
I don't understand how to do this functionality, put a point on PDF. I found this : https://github.com/barteksc/AndroidPdfViewer/issues/554
So it's possible but how ? I don't get it.
I suppose I need to create a bitmap, but I can't draw on the PDF, or put a marker.
Thanks for your time.
You have a sample file in his repo.
If you go to this location he has already created the method on how to load a pdf! Then if you go to this link you will see that he has created the class and has included good comments
Render page fragment on {#link Surface}
Page must be opened before rendering.
public void renderPage(PdfDocument doc, Surface surface, int pageIndex,
int startX, int startY, int drawSizeX, int drawSizeY) {
renderPage(doc, surface, pageIndex, startX, startY, drawSizeX, drawSizeY, false);
}
The one that you are searching is bookmark method
/** Get table of contents (bookmarks) for given document */
public List<PdfDocument.Bookmark> getTableOfContents(PdfDocument doc) {
synchronized (lock) {
List<PdfDocument.Bookmark> topLevel = new ArrayList<>();
Long first = nativeGetFirstChildBookmark(doc.mNativeDocPtr, null);
if (first != null) {
recursiveGetBookmark(topLevel, doc, first);
}
return topLevel;
}
}
However keep in mind that it might be necessary to use Async Tasks to download a pdf!

How to show images taken 10 minutes ago in android gallery?

I want the ability to allow the user to choose an image from the gallery,
but only images were taken, for example, 10 minutes ago (maybe using Time Created Metadata?).
There are examples of how to open gallery and choose an image:
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
However, I only need images which were taken 10 minutes ago.
Does anyone have an idea?
I might be wrong but I don't think you can achieve this directly by using the Intent.ACTION_PICK into the Gallery. I think, there is a possible way with MediaStore.Images.ImageColumns.DATE_TAKEN and a Cursor as you can see in this answer. However, I did not find the right way to do it.
Then, you can do a workaround: create your own Gallery into your app. Select all the pictures from the Camera folder, filter them, and display only which are taken x min ago into your own Gallery - a simple GridView. I think this might be easy to do:
Init the vars:
// FileArray
private File[] aFile;
// ArrayList
private ArrayList<String> aImagePath = new ArrayList<String>();
Get the DCIM Camera folder:
File fPath = new File(Environment
.getExternalStorageDirectory().toString() + "/DCIM/Camera");
Create a FileArray and list the files in this folder:
// use a FilenameFilter to have only the pictures in JPG
aFile = fPath.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".jpg");
}
});
For each file, get the last modified date and populate an ArrayList<String>:
for(int i=0; i < aFile.length; i++) {
long lastDate = aFile[i].lastModified(); // get last modified date
long nowTime = nDate.getTime(); // get the current time to compare
if(nowTime - lastDate < 600*1000) { // if less than 10 min
String pathFile = aFile[i].getPath();
aImagePath.add(pathFile); // populate the Array
}
}
Finally, reverse the Array to have the most recent pictures at the first place and display them:
if(aImagePath.size() != 0) {
Collections.reverse(aImagePath); // reverse the Array
// Call an AsyncTask to create and retrieve each Bitmap
// then, in onPostExecute(), populate the Adapter of the GridView
} else {
// No pictures taken 10 min ago!
}
Actually, in the AsyncTask, you will have to deal with the Bitmap options to save memory... I tested this in a GridView into a Fragment and it worked well. You can find the references I used above:
Using File.listFiles with FileNameExtensionFilter
How to get a file's creation date?
Get File Creation Time
How to display selected image gallery in ImageView?
Maybe someone has a better solution, but this above does the trick and displays only the images taken 10 min ago with the Camera's device. I hope this will help you.

Categories

Resources