Update files

This commit is contained in:
Victor Shcherb 2015-08-01 20:17:51 +02:00
parent 3c3851ad87
commit 279bc00f0a
12 changed files with 525 additions and 153 deletions

View file

@ -535,40 +535,31 @@ public class BinaryMapIndexReader {
return names;
}
public LatLon getRegionCenter(String name) {
AddressRegion rg = getRegionByName(name);
if (rg != null) {
return rg.calculatedCenter;
public LatLon getRegionCenter() {
for(AddressRegion r : addressIndexes) {
if(r.calculatedCenter != null)
return r.calculatedCenter;
}
return null;
}
private AddressRegion getRegionByName(String name){
for(AddressRegion r : addressIndexes){
if(r.name.equals(name)){
return r;
}
}
return null;
public List<City> getCities(SearchRequest<City> resultMatcher,
int cityType) throws IOException {
return getCities(resultMatcher, null, null, cityType);
}
public List<City> getCities(String region, SearchRequest<City> resultMatcher,
int cityType) throws IOException {
return getCities(region, resultMatcher, null, null, cityType);
}
public List<City> getCities(String region, SearchRequest<City> resultMatcher, StringMatcher matcher, String lang,
int cityType) throws IOException {
public List<City> getCities(SearchRequest<City> resultMatcher, StringMatcher matcher, String lang, int cityType)
throws IOException {
List<City> cities = new ArrayList<City>();
AddressRegion r = getRegionByName(region);
if(r == null) {
return cities;
}
for(CitiesBlock block : r.cities) {
if(block.type == cityType) {
codedIS.seek(block.filePointer);
int old = codedIS.pushLimit(block.length);
addressAdapter.readCities(cities, resultMatcher, matcher, r.attributeTagsTable);
codedIS.popLimit(old);
for (AddressRegion r : addressIndexes) {
for (CitiesBlock block : r.cities) {
if (block.type == cityType) {
codedIS.seek(block.filePointer);
int old = codedIS.pushLimit(block.length);
addressAdapter.readCities(cities, resultMatcher, matcher, r.attributeTagsTable);
codedIS.popLimit(old);
}
}
}
return cities;
@ -2260,9 +2251,8 @@ public class BinaryMapIndexReader {
private static void testAddressSearch(BinaryMapIndexReader reader) throws IOException {
// test address index search
String reg = reader.getRegionNames().get(0);
final Map<String, Integer> streetFreq = new HashMap<String, Integer>();
List<City> cs = reader.getCities(reg, null, BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE);
List<City> cs = reader.getCities(null, BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE);
for(City c : cs){
int buildings = 0;
reader.preloadStreets(c, null);
@ -2275,7 +2265,7 @@ public class BinaryMapIndexReader {
println(c.getName() + " " + c.getLocation() + " " + c.getStreets().size() + " " + buildings + " " + c.getEnName(true) + " " + c.getName("ru"));
}
// int[] count = new int[1];
List<City> villages = reader.getCities(reg, buildAddressRequest((ResultMatcher<City>) null), BinaryMapAddressReaderAdapter.VILLAGES_TYPE);
List<City> villages = reader.getCities(buildAddressRequest((ResultMatcher<City>) null), BinaryMapAddressReaderAdapter.VILLAGES_TYPE);
for(City v : villages) {
reader.preloadStreets(v, null);
for(Street s : v.getStreets()){

View file

@ -27,11 +27,9 @@ public class NetworkUtils {
private static Proxy proxy = null;
public static String sendGetRequest(String urlText, String userNamePassword){
URL url;
public static String sendGetRequest(String urlText, String userNamePassword, StringBuilder responseBody){
try {
log.info("GET : " + urlText);
url = new URL(urlText);
HttpURLConnection conn = getHttpURLConnection(urlText);
conn.setDoInput(true);
conn.setDoOutput(false);
@ -39,14 +37,13 @@ public class NetworkUtils {
if(userNamePassword != null) {
conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$
}
conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
log.info("Response code and message : " + conn.getResponseCode() + " " + conn.getResponseMessage());
if(conn.getResponseCode() != 200){
return conn.getResponseMessage();
}
InputStream is = conn.getInputStream();
StringBuilder responseBody = new StringBuilder();
responseBody.setLength(0);
if (is != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8")); //$NON-NLS-1$
String s;
@ -62,12 +59,7 @@ public class NetworkUtils {
}
is.close();
}
String response = responseBody.toString();
log.info("Response : " + response);
if(response.startsWith("OK")){
return null;
}
return response;
return null;
} catch (IOException e) {
log.error(e.getMessage(), e);
return e.getMessage();

View file

@ -1,6 +1,7 @@
package net.osmand.util;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
@ -8,7 +9,9 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
@ -45,6 +48,16 @@ public class Algorithms {
}
public static String getFileNameWithoutExtension(File f) {
String name = f.getName();
int i = name.indexOf('.');
if(i >= 0) {
name = name.substring(0, i);
}
return name;
}
public static File[] getSortedFilesVersions(File dir){
File[] listFiles = dir.listFiles();
@ -306,6 +319,25 @@ public class Algorithms {
}
public static StringBuilder readFromInputStream(InputStream i) throws IOException {
StringBuilder responseBody = new StringBuilder();
responseBody.setLength(0);
if (i != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$
String s;
boolean f = true;
while ((s = in.readLine()) != null) {
if (!f) {
responseBody.append("\n"); //$NON-NLS-1$
} else {
f = false;
}
responseBody.append(s);
}
}
return responseBody;
}
public static boolean removeAllFiles(File f) {
if (f == null) {
return false;

View file

@ -9,6 +9,7 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
-->
<string name="no_updates_available">No updates available</string>
<string name="download_live_updates">Live updates</string>
<string name="rendering_value_default13_name">Default (13)</string>
<string name="rendering_value_defaultTranslucentCyan_name">Default (translucent cyan)</string>

View file

@ -118,7 +118,7 @@ public class DownloadActivityType {
}
public boolean isZipStream(OsmandApplication ctx, IndexItem indexItem) {
return HILLSHADE_FILE != this && LIVE_UPDATES_FILE != this;
return HILLSHADE_FILE != this;
}
public boolean isZipFolder(OsmandApplication ctx, IndexItem indexItem) {
@ -161,6 +161,8 @@ public class DownloadActivityType {
public String getUrlSuffix(OsmandApplication ctx) {
if (this== DownloadActivityType.ROADS_FILE) {
return "&road=yes";
} else if (this == DownloadActivityType.LIVE_UPDATES_FILE) {
return "&osmc=yes";
} else if (this == DownloadActivityType.SRTM_COUNTRY_FILE) {
return "&srtmcountry=yes";
} else if (this == DownloadActivityType.WIKIPEDIA_FILE) {

View file

@ -8,6 +8,7 @@ import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@ -265,10 +266,13 @@ public class DownloadFileHelper {
progress.startTask(taskName, len / 1024);
if (!de.zipStream) {
copyFile(de, progress, fin, len, fin, de.fileToDownload);
} else if(de.urlToDownload.contains(".gz")) {
GZIPInputStream zipIn = new GZIPInputStream(fin);
copyFile(de, progress, fin, len, zipIn, de.fileToDownload);
} else {
if (de.unzipFolder) {
de.fileToDownload.mkdirs();
}
}
ZipInputStream zipIn = new ZipInputStream(fin);
ZipEntry entry = null;
boolean first = true;
@ -304,7 +308,8 @@ public class DownloadFileHelper {
fin.close();
}
private void copyFile(DownloadEntry de, IProgress progress, CountingMultiInputStream countIS, int length, InputStream toRead, File targetFile)
private void copyFile(DownloadEntry de, IProgress progress,
CountingMultiInputStream countIS, int length, InputStream toRead, File targetFile)
throws IOException {
targetFile.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(targetFile);

View file

@ -52,6 +52,9 @@ import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
import net.osmand.plus.activities.OsmandExpandableListFragment;
import net.osmand.plus.dialogs.DirectionsDialogs;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.resources.IncrementalChangesManager;
import net.osmand.plus.resources.IncrementalChangesManager.IncrementalUpdate;
import net.osmand.plus.resources.IncrementalChangesManager.IncrementalUpdateList;
import net.osmand.util.Algorithms;
import java.io.File;
@ -1168,15 +1171,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
String fileName = info.getFileName();
Toast.makeText(getActivity(), fileName, Toast.LENGTH_SHORT).show();
SimpleDateFormat sdf = new SimpleDateFormat("yy_MM_dd");
fileName = fileName.substring(0, fileName.indexOf('.')) + "_" + sdf.format(new Date()) + ".obf";
IndexItem ii =
new IndexItem(fileName, "Incremental update", new Date().getTime(), "1",
1000, 1000, DownloadActivityType.LIVE_UPDATES_FILE);
getDownloadActivity().addToDownload(ii);
runLiveUpdate(info);
return true;
}
});
@ -1184,7 +1179,42 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment {
optionsMenu.show();
}
private void runLiveUpdate(final LocalIndexInfo info) {
final String fnExt = Algorithms.getFileNameWithoutExtension(new File(info.getFileName()));
new AsyncTask<Object, Object, IncrementalUpdateList>() {
protected void onPreExecute() {
getDownloadActivity().setSupportProgressBarIndeterminateVisibility(true);
};
@Override
protected IncrementalUpdateList doInBackground(Object... params) {
IncrementalChangesManager cm = getMyApplication().getResourceManager().getChangesManager();
return cm.getUpdatesByMonth(fnExt);
}
protected void onPostExecute(IncrementalUpdateList result) {
getDownloadActivity().setSupportProgressBarIndeterminateVisibility(false);
if (result.errorMessage != null) {
Toast.makeText(getDownloadActivity(), result.errorMessage, Toast.LENGTH_SHORT).show();
} else {
List<IncrementalUpdate> ll = result.getItemsForUpdate();
for (IncrementalUpdate iu : ll) {
IndexItem ii = new IndexItem(iu.fileName, "Incremental update", iu.timestamp, iu.sizeText,
iu.contentSize, iu.containerSize, DownloadActivityType.LIVE_UPDATES_FILE);
getDownloadActivity().addToDownload(ii);
}
}
};
}.execute(new Object[] { fnExt });
}
private DownloadActivity getDownloadActivity(){ return (DownloadActivity)getActivity();}
private DownloadActivity getDownloadActivity() {
return (DownloadActivity) getActivity();
}
}

View file

@ -6,7 +6,6 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import net.osmand.PlatformUtil;
@ -16,6 +15,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
@ -23,19 +23,14 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
private static final Log log = PlatformUtil.getLog(OsmBugsRemoteUtil.class);
static String getNotesApi()
{
static String getNotesApi() {
final int deviceApiVersion = android.os.Build.VERSION.SDK_INT;
String RETURN_API;
if (deviceApiVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) {
RETURN_API = "https://api.openstreetmap.org/api/0.6/notes";
}
else {
} else {
RETURN_API = "http://api.openstreetmap.org/api/0.6/notes";
}
return RETURN_API;
}
@ -104,26 +99,9 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
boolean ok = connection.getResponseCode() == HttpURLConnection.HTTP_OK;
log.info(msg); //$NON-NLS-1$
// populate return fields.
StringBuilder responseBody = new StringBuilder();
if (true) {
responseBody.setLength(0);
InputStream i = connection.getInputStream();
if (i != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); //$NON-NLS-1$
String s;
boolean f = true;
while ((s = in.readLine()) != null) {
if (!f) {
responseBody.append("\n"); //$NON-NLS-1$
} else {
f = false;
}
responseBody.append(s);
}
}
log.info("Response : " + responseBody); //$NON-NLS-1$
}
StringBuilder responseBody = Algorithms.readFromInputStream(connection.getInputStream());
log.info("Response : " + responseBody); //$NON-NLS-1$
connection.disconnect();
if (!ok) {
return msg + "\n" + responseBody;

View file

@ -20,7 +20,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import net.osmand.IProgress;
import net.osmand.NativeLibrary.NativeSearchResult;
@ -127,12 +126,12 @@ public class MapRenderRepositories {
}
public void initializeNewResource(final IProgress progress, File file, BinaryMapIndexReader reader) {
if (files.containsKey(file.getAbsolutePath())) {
closeConnection(files.get(file.getAbsolutePath()), file.getAbsolutePath());
if (files.containsKey(file.getName())) {
closeConnection(file.getName());
}
LinkedHashMap<String, BinaryMapIndexReader> cpfiles = new LinkedHashMap<String, BinaryMapIndexReader>(files);
cpfiles.put(file.getAbsolutePath(), reader);
cpfiles.put(file.getName(), reader);
files = cpfiles;
}
@ -144,21 +143,23 @@ public class MapRenderRepositories {
return prevBmpLocation;
}
protected void closeConnection(BinaryMapIndexReader c, String file) {
public void closeConnection(String file) {
LinkedHashMap<String, BinaryMapIndexReader> cpfiles = new LinkedHashMap<String, BinaryMapIndexReader>(files);
cpfiles.remove(file);
BinaryMapIndexReader bmir = cpfiles.remove(file);
files = cpfiles;
if(nativeFiles.contains(file)){
if (nativeFiles.contains(file)) {
NativeOsmandLibrary lib = NativeOsmandLibrary.getLoadedLibrary();
if(lib != null) {
if (lib != null) {
lib.closeMapFile(file);
nativeFiles.remove(file);
}
}
try {
c.close();
} catch (IOException e) {
e.printStackTrace();
if (bmir != null) {
try {
bmir.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@ -178,7 +179,7 @@ public class MapRenderRepositories {
bmp = null;
bmpLocation = null;
for (String f : new ArrayList<String>(files.keySet())) {
closeConnection(files.get(f), f);
closeConnection(f);
}
}

View file

@ -0,0 +1,309 @@
package net.osmand.plus.resources;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.R;
import net.osmand.util.Algorithms;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
public class IncrementalChangesManager {
private static final String URL = "http://download.osmand.net/check_live.php";
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(IncrementalChangesManager.class);
private ResourceManager resourceManager;
private final Map<String, RegionUpdateFiles> regions = new ConcurrentHashMap<String, IncrementalChangesManager.RegionUpdateFiles>();
public IncrementalChangesManager(ResourceManager resourceManager) {
this.resourceManager = resourceManager;
}
public void indexMainMap(File f, long dateCreated) {
String nm = Algorithms.getFileNameWithoutExtension(f).toLowerCase();
if(!regions.containsKey(nm)) {
regions.put(nm, new RegionUpdateFiles(nm));
}
RegionUpdateFiles regionUpdateFiles = regions.get(nm);
regionUpdateFiles.mainFile = f;
regionUpdateFiles.mainFileInit = dateCreated;
if (!regionUpdateFiles.monthUpdates.isEmpty()) {
List<String> list = new ArrayList<String>(regionUpdateFiles.monthUpdates.keySet());
for (String month : list) {
RegionUpdate ru = regionUpdateFiles.monthUpdates.get(month);
if (ru.obfCreated < dateCreated) {
resourceManager.closeFile(ru.file.getName());
regionUpdateFiles.monthUpdates.remove(month);
ru.file.delete();
}
}
}
if (!regionUpdateFiles.dayUpdates.isEmpty()) {
ArrayList<String> list = new ArrayList<String>(regionUpdateFiles.dayUpdates.keySet());
for (String month : list) {
Iterator<RegionUpdate> it = regionUpdateFiles.dayUpdates.get(month).iterator();
RegionUpdate monthRu = regionUpdateFiles.monthUpdates.get(month);
while (it.hasNext()) {
RegionUpdate ru = it.next();
if (ru.obfCreated < dateCreated || (monthRu != null && ru.obfCreated < monthRu.obfCreated)) {
resourceManager.closeFile(ru.file.getName());
it.remove();
ru.file.delete();
}
}
}
}
}
public boolean index(File f, long dateCreated, BinaryMapIndexReader mapReader) {
String index = Algorithms.getFileNameWithoutExtension(f).toLowerCase();
if(index.length() <= 9 || index.charAt(index.length() - 9) != '_'){
return false;
}
String nm = index.substring(0, index.length() - 9);
String date = index.substring(index.length() - 9 + 1);
if(!regions.containsKey(nm)) {
regions.put(nm, new RegionUpdateFiles(nm));
}
RegionUpdateFiles regionUpdateFiles = regions.get(nm);
return regionUpdateFiles.addUpdate(date, f, dateCreated);
}
protected static String formatSize(long vl) {
return (float) ((vl * 1000 / (1 << 20l)) / 1000.0f) + "";
}
public static long calculateSize(List<IncrementalUpdate> list) {
long l = 0;
for(IncrementalUpdate iu : list) {
l += iu.containerSize;
}
return l;
}
protected class RegionUpdate {
protected File file;
protected String date;
protected long obfCreated;
}
protected class RegionUpdateFiles {
protected String nm;
protected File mainFile;
protected long mainFileInit;
TreeMap<String, List<RegionUpdate>> dayUpdates = new TreeMap<String, List<RegionUpdate>>();
TreeMap<String, RegionUpdate> monthUpdates = new TreeMap<String, RegionUpdate>();
public RegionUpdateFiles(String nm) {
this.nm = nm;
}
public boolean addUpdate(String date, File file, long dateCreated) {
String monthYear = date.substring(0, 5);
RegionUpdate ru = new RegionUpdate();
ru.date = date;
ru.file = file;
ru.obfCreated = dateCreated;
if(date.endsWith("00")) {
monthUpdates.put(monthYear, ru);
} else {
if (!dayUpdates.containsKey(date)) {
dayUpdates.put(monthYear, new ArrayList<IncrementalChangesManager.RegionUpdate>());
}
dayUpdates.get(monthYear).add(ru);
}
return true;
}
}
public class IncrementalUpdateList {
public TreeMap<String, IncrementalUpdateGroupByMonth> updateByMonth =
new TreeMap<String, IncrementalUpdateGroupByMonth>();
public String errorMessage;
public RegionUpdateFiles updateFiles;
public boolean isPreferrableLimitForDayUpdates(String monthYearPart, List<IncrementalUpdate> dayUpdates) {
List<RegionUpdate> lst = updateFiles.dayUpdates.get(monthYearPart);
if(lst == null || lst.size() < 10) {
return true;
}
return false;
}
public List<IncrementalUpdate> getItemsForUpdate() {
Iterator<IncrementalUpdateGroupByMonth> it = updateByMonth.values().iterator();
List<IncrementalUpdate> ll = new ArrayList<IncrementalUpdate>();
while(it.hasNext()) {
IncrementalUpdateGroupByMonth n = it.next();
if(it.hasNext()) {
if(!n.isMonthUpdateApplicable()) {
return null;
}
ll.addAll(n.getMonthUpdate());
} else {
if(n.isDayUpdateApplicable() && isPreferrableLimitForDayUpdates(n.monthYearPart, n.getDayUpdates())) {
ll.addAll(n.getDayUpdates());
} else if(n.isMonthUpdateApplicable()) {
ll.addAll(n.getMonthUpdate());
} else {
return null;
}
}
}
return ll;
}
public void addUpdate(IncrementalUpdate iu) {
String dtMonth = iu.date.substring(0, 5);
if(!updateByMonth.containsKey(dtMonth)) {
IncrementalUpdateGroupByMonth iubm = new IncrementalUpdateGroupByMonth(dtMonth);
updateByMonth.put(dtMonth, iubm);
}
IncrementalUpdateGroupByMonth mm = updateByMonth.get(dtMonth);
if(iu.isMonth()) {
mm.monthUpdate = iu;
} else {
mm.dayUpdates.add(iu);
}
}
}
protected static class IncrementalUpdateGroupByMonth {
public final String monthYearPart ;
public List<IncrementalUpdate> dayUpdates = new ArrayList<IncrementalUpdate>();
public IncrementalUpdate monthUpdate;
public long calculateSizeMonthUpdates() {
return calculateSize(getMonthUpdate());
}
public long calculateSizeDayUpdates() {
return calculateSize(getDayUpdates());
}
public boolean isMonthUpdateApplicable() {
return monthUpdate != null;
}
public boolean isDayUpdateApplicable() {
boolean inLimits = dayUpdates.size() > 0 && dayUpdates.size() < 4;
if(!inLimits) {
return false;
}
return true;
}
public List<IncrementalUpdate> getMonthUpdate() {
List<IncrementalUpdate> ll = new ArrayList<IncrementalUpdate>();
if(monthUpdate == null) {
return ll;
}
ll.add(monthUpdate);
for(IncrementalUpdate iu : dayUpdates) {
if(iu.timestamp > monthUpdate.timestamp) {
ll.add(iu);
}
}
return ll;
}
public List<IncrementalUpdate> getDayUpdates() {
return dayUpdates;
}
public IncrementalUpdateGroupByMonth(String monthYearPart ) {
this.monthYearPart = monthYearPart;
}
}
public static class IncrementalUpdate {
String date = "";
public long timestamp;
public String sizeText = "";
public long containerSize;
public long contentSize;
public String fileName;
public boolean isMonth() {
return date.endsWith("00");
}
@Override
public String toString() {
return "Update " + fileName + " " + sizeText + " MB " + date;
}
}
private List<IncrementalUpdate> getIncrementalUpdates(String file, long timestamp) throws IOException,
XmlPullParserException {
String url = URL + "?timestamp=" + timestamp + "&file=" + URLEncoder.encode(file);
HttpURLConnection conn = NetworkUtils.getHttpURLConnection(url);
XmlPullParser parser = PlatformUtil.newXMLPullParser();
parser.setInput(conn.getInputStream(), "UTF-8");
List<IncrementalUpdate> lst = new ArrayList<IncrementalUpdate>();
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() == XmlPullParser.START_TAG) {
if (parser.getName().equals("update")) {
IncrementalUpdate dt = new IncrementalUpdate();
dt.date = parser.getAttributeValue("", "updateDate");
dt.containerSize = Long.parseLong(parser.getAttributeValue("", "containerSize"));
dt.contentSize = Long.parseLong(parser.getAttributeValue("", "contentSize"));
dt.sizeText = parser.getAttributeValue("", "size");
dt.timestamp = Long.parseLong(parser.getAttributeValue("", "timestamp"));
dt.fileName = parser.getAttributeValue("", "name");
lst.add(dt);
}
}
}
return lst;
}
public IncrementalUpdateList getUpdatesByMonth(String fileName) {
IncrementalUpdateList iul = new IncrementalUpdateList();
RegionUpdateFiles ruf = regions.get(fileName.toLowerCase());
iul.updateFiles = ruf;
if(ruf == null) {
iul.errorMessage = resourceManager.getContext().getString(R.string.no_updates_available);
return iul;
}
long timestamp = ruf.mainFileInit;
for (RegionUpdate ru : ruf.monthUpdates.values()) {
timestamp = Math.max(ru.obfCreated, timestamp);
}
for (List<RegionUpdate> l : ruf.dayUpdates.values()) {
for (RegionUpdate ru : l) {
timestamp = Math.max(ru.obfCreated, timestamp);
}
}
try {
List<IncrementalUpdate> lst = getIncrementalUpdates(fileName, timestamp);
for(IncrementalUpdate iu : lst) {
iul.addUpdate(iu);
}
} catch (Exception e) {
iul.errorMessage = e.getMessage();
e.printStackTrace();
log.error(e.getMessage(), e);
}
return iul;
}
}

View file

@ -25,7 +25,6 @@ import net.osmand.data.MapObject;
import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree;
import net.osmand.data.Street;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings.OsmandPreference;
import net.osmand.util.MapUtils;
@ -35,7 +34,6 @@ import org.apache.commons.logging.Log;
public class RegionAddressRepositoryBinary implements RegionAddressRepository {
private static final Log log = PlatformUtil.getLog(RegionAddressRepositoryBinary.class);
private BinaryMapIndexReader file;
private String region;
private LinkedHashMap<Long, City> cities = new LinkedHashMap<Long, City>();
@ -48,11 +46,10 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
private ResourceManager mgr;
private OsmandPreference<String> langSetting;
public RegionAddressRepositoryBinary(ResourceManager mgr, BinaryMapIndexReader file, String name, String fileName) {
public RegionAddressRepositoryBinary(ResourceManager mgr, BinaryMapIndexReader file, String fileName) {
this.mgr = mgr;
langSetting = mgr.getContext().getSettings().MAP_PREFERRED_LOCALE;
this.file = file;
this.region = name;
this.fileName = fileName;
this.collator = OsmAndCollator.primaryCollator();
this.postCodes = new TreeMap<String, City>(OsmAndCollator.primaryCollator());
@ -68,7 +65,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
public synchronized void preloadCities(ResultMatcher<City> resultMatcher) {
if (cities.isEmpty()) {
try {
List<City> cs = file.getCities(region, BinaryMapIndexReader.buildAddressRequest(resultMatcher),
List<City> cs = file.getCities(BinaryMapIndexReader.buildAddressRequest(resultMatcher),
BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE);
LinkedHashMap<Long, City> ncities = new LinkedHashMap<Long, City>();
for (City c : cs) {
@ -189,7 +186,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
if (/*name.length() >= 2 && Algorithms.containsDigit(name) && */searchVillages) {
// also try to identify postcodes
String uName = name.toUpperCase();
List<City> foundCities = file.getCities(region, BinaryMapIndexReader.buildAddressRequest(resultMatcher),
List<City> foundCities = file.getCities(BinaryMapIndexReader.buildAddressRequest(resultMatcher),
new CollatorStringMatcher(uName, StringMatcherMode.CHECK_CONTAINS), lang,
BinaryMapAddressReaderAdapter.POSTCODES_TYPE);
for (City code : foundCities) {
@ -216,7 +213,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
int initialsize = citiesToFill.size();
if (/*name.length() >= 3 && */searchVillages) {
List<City> foundCities = file.getCities(region, BinaryMapIndexReader.buildAddressRequest(new ResultMatcher<City>() {
List<City> foundCities = file.getCities(BinaryMapIndexReader.buildAddressRequest(new ResultMatcher<City>() {
List<City> cache = new ArrayList<City>();
@Override
public boolean publish(City c) {
@ -275,7 +272,10 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override
public String getName() {
return region;
if(fileName.indexOf('.') != -1) {
return fileName.substring(0, fileName.indexOf('.'));
}
return fileName;
}
@Override
@ -301,7 +301,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
preloadCities(null);
if (!cities.containsKey(id)) {
try {
file.getCities(region, BinaryMapIndexReader.buildAddressRequest(new ResultMatcher<City>() {
file.getCities(BinaryMapIndexReader.buildAddressRequest(new ResultMatcher<City>() {
boolean canceled = false;
@Override
@ -356,7 +356,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository {
@Override
public LatLon getEstimatedRegionCenter() {
return file.getRegionCenter(region);
return file.getRegionCenter();
}

View file

@ -6,7 +6,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.text.Collator;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
@ -14,7 +13,6 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import net.osmand.AndroidUtils;
@ -111,25 +109,21 @@ public class ResourceManager {
// Indexes
private final Map<String, RegionAddressRepository> addressMap = new TreeMap<String, RegionAddressRepository>(Collator.getInstance());
protected final List<AmenityIndexRepository> amenityRepositories = new ArrayList<AmenityIndexRepository>();
protected final List<TransportIndexRepository> transportRepositories = new ArrayList<TransportIndexRepository>();
private final Map<String, RegionAddressRepository> addressMap = new ConcurrentHashMap<String, RegionAddressRepository>();
protected final Map<String, AmenityIndexRepository> amenityRepositories = new ConcurrentHashMap<String, AmenityIndexRepository>();
protected final Map<String, String> indexFileNames = new ConcurrentHashMap<String, String>();
protected final Map<String, String> liveUpdatesFiles = new ConcurrentHashMap<String, String>();
protected final Map<String, String> basemapFileNames = new ConcurrentHashMap<String, String>();
protected final Map<String, BinaryMapIndexReader> routingMapFiles = new ConcurrentHashMap<String, BinaryMapIndexReader>();
protected final Map<String, TransportIndexRepository> transportRepositories = new ConcurrentHashMap<String, TransportIndexRepository>();
protected final IncrementalChangesManager changesManager = new IncrementalChangesManager(this);
protected final MapRenderRepositories renderer;
protected final MapTileDownloader tileDownloader;
public final AsyncLoadingThread asyncLoadingThread = new AsyncLoadingThread(this);
private HandlerThread renderingBufferImageThread;
protected boolean internetIsNotAccessible = false;
@ -615,7 +609,6 @@ public class ResourceManager {
if (indCache.exists()) {
try {
cachedOsmandIndexes.readFromFile(indCache, CachedOsmandIndexes.VERSION);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
@ -623,63 +616,78 @@ public class ResourceManager {
for (File f : files) {
progress.startTask(context.getString(R.string.indexing_map) + " " + f.getName(), -1); //$NON-NLS-1$
try {
BinaryMapIndexReader index = null;
BinaryMapIndexReader mapReader = null;
try {
index = cachedOsmandIndexes.getReader(f);
if (index.getVersion() != IndexConstants.BINARY_MAP_VERSION) {
index = null;
mapReader = cachedOsmandIndexes.getReader(f);
if (mapReader.getVersion() != IndexConstants.BINARY_MAP_VERSION) {
mapReader = null;
}
if (index != null) {
renderer.initializeNewResource(progress, f, index);
if (mapReader != null) {
renderer.initializeNewResource(progress, f, mapReader);
}
} catch (IOException e) {
log.error(String.format("File %s could not be read", f.getName()), e);
}
if (index == null || (Version.isFreeVersion(context) &&
if (mapReader == null || (Version.isFreeVersion(context) &&
(f.getName().contains("_wiki") || f.getName().contains(".wiki"))
)) {
warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$
} else {
if (index.isBasemap()) {
if (mapReader.isBasemap()) {
basemapFileNames.put(f.getName(), f.getName());
}
long dateCreated = index.getDateCreated();
long dateCreated = mapReader.getDateCreated();
if (dateCreated == 0) {
dateCreated = f.lastModified();
}
if(f.getParentFile().getName().equals(IndexConstants.LIVE_INDEX_DIR)) {
liveUpdatesFiles.put(f.getName(), dateFormat.format(dateCreated)); //$NON-NLS-1$
boolean toUse = changesManager.index(f, dateCreated, mapReader);
if(!toUse) {
try {
mapReader.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
continue;
}
} else {
changesManager.indexMainMap(f, dateCreated);
indexFileNames.put(f.getName(), dateFormat.format(dateCreated)); //$NON-NLS-1$
}
for (String rName : index.getRegionNames()) {
// skip duplicate names (don't make collision between getName() and name in the map)
// it can be dangerous to use one file to different indexes if it is multithreaded
RegionAddressRepositoryBinary rarb = new RegionAddressRepositoryBinary(this, index, rName, f.getName());
addressMap.put(rName, rarb);
}
if (index.hasTransportData()) {
if (!mapReader.getRegionNames().isEmpty()) {
try {
RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$
transportRepositories.add(new TransportIndexRepositoryBinary(new BinaryMapIndexReader(raf, index)));
RegionAddressRepositoryBinary rarb = new RegionAddressRepositoryBinary(this,
new BinaryMapIndexReader(raf, mapReader), f.getName());
addressMap.put(f.getName(), rarb);
} catch (IOException e) {
log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$
warnings.add(MessageFormat.format(
context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$
}
}
if (mapReader.hasTransportData()) {
try {
RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$
transportRepositories.put(f.getName(), new TransportIndexRepositoryBinary(new BinaryMapIndexReader(raf, mapReader)));
} catch (IOException e) {
log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$
warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$
}
}
if (index.containsRouteData()) {
if (mapReader.containsRouteData()) {
try {
RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$
routingMapFiles.put(f.getAbsolutePath(), new BinaryMapIndexReader(raf, index));
routingMapFiles.put(f.getName(), new BinaryMapIndexReader(raf, mapReader));
} catch (IOException e) {
log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$
warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$
}
}
if (index.containsPoiData()) {
if (mapReader.containsPoiData()) {
try {
RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$
amenityRepositories.add(new AmenityIndexRepositoryBinary(new BinaryMapIndexReader(raf, index)));
amenityRepositories.put(f.getName(), new AmenityIndexRepositoryBinary(new BinaryMapIndexReader(raf, mapReader)));
} catch (IOException e) {
log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$
warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$
@ -722,7 +730,7 @@ public class ResourceManager {
searchAmenitiesInProgress = true;
try {
if (!filter.isEmpty()) {
for (AmenityIndexRepository index : amenityRepositories) {
for (AmenityIndexRepository index : amenityRepositories.values()) {
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
List<Amenity> r = index.searchAmenities(MapUtils.get31TileNumberY(topLatitude),
MapUtils.get31TileNumberX(leftLongitude), MapUtils.get31TileNumberY(bottomLatitude),
@ -757,7 +765,7 @@ public class ResourceManager {
rightLongitude = Math.max(rightLongitude, l.getLongitude());
}
if (!filter.isEmpty()) {
for (AmenityIndexRepository index : amenityRepositories) {
for (AmenityIndexRepository index : amenityRepositories.values()) {
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
repos.add(index);
}
@ -780,7 +788,7 @@ public class ResourceManager {
public boolean containsAmenityRepositoryToSearch(boolean searchByName){
for (AmenityIndexRepository index : amenityRepositories) {
for (AmenityIndexRepository index : amenityRepositories.values()) {
if(searchByName){
if(index instanceof AmenityIndexRepositoryBinary){
return true;
@ -797,7 +805,7 @@ public class ResourceManager {
double lat, double lon, ResultMatcher<Amenity> matcher) {
List<Amenity> amenities = new ArrayList<Amenity>();
List<AmenityIndexRepositoryBinary> list = new ArrayList<AmenityIndexRepositoryBinary>();
for (AmenityIndexRepository index : amenityRepositories) {
for (AmenityIndexRepository index : amenityRepositories.values()) {
if (index instanceof AmenityIndexRepositoryBinary) {
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
if(index.checkContains(lat, lon)){
@ -832,7 +840,7 @@ public class ResourceManager {
public Map<PoiCategory, List<String>> searchAmenityCategoriesByName(String searchQuery, double lat, double lon) {
Map<PoiCategory, List<String>> map = new LinkedHashMap<PoiCategory, List<String>>();
for (AmenityIndexRepository index : amenityRepositories) {
for (AmenityIndexRepository index : amenityRepositories.values()) {
if (index instanceof AmenityIndexRepositoryBinary) {
if (index.checkContains(lat, lon)) {
((AmenityIndexRepositoryBinary) index).searchAmenityCategoriesByName(searchQuery, map);
@ -857,7 +865,7 @@ public class ResourceManager {
////////////////////////////////////////////// Working with transport ////////////////////////////////////////////////
public List<TransportIndexRepository> searchTransportRepositories(double latitude, double longitude) {
List<TransportIndexRepository> repos = new ArrayList<TransportIndexRepository>();
for (TransportIndexRepository index : transportRepositories) {
for (TransportIndexRepository index : transportRepositories.values()) {
if (index.checkContains(latitude,longitude)) {
repos.add(index);
}
@ -868,7 +876,7 @@ public class ResourceManager {
public void searchTransportAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, List<TransportStop> toFill){
List<TransportIndexRepository> repos = new ArrayList<TransportIndexRepository>();
for (TransportIndexRepository index : transportRepositories) {
for (TransportIndexRepository index : transportRepositories.values()) {
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
if (!index.checkCachedObjects(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, toFill, true)) {
repos.add(index);
@ -906,8 +914,32 @@ public class ResourceManager {
////////////////////////////////////////////// Closing methods ////////////////////////////////////////////////
public void closeFile(String fileName) {
AmenityIndexRepository rep = amenityRepositories.remove(fileName);
if(rep != null) {
rep.close();
}
RegionAddressRepository rar = addressMap.remove(fileName);
if(rar != null) {
rar.close();
}
TransportIndexRepository tir = transportRepositories.remove(fileName);
if(tir != null) {
tir.close();
}
BinaryMapIndexReader rmp = routingMapFiles.remove(fileName);
if(rmp != null) {
try {
rmp.close();
} catch (IOException e) {
log.error(e, e);
}
}
renderer.closeConnection(fileName);
}
public void closeAmenities(){
for(AmenityIndexRepository r : amenityRepositories){
for(AmenityIndexRepository r : amenityRepositories.values()){
r.close();
}
amenityRepositories.clear();
@ -921,7 +953,7 @@ public class ResourceManager {
}
public void closeTransport(){
for(TransportIndexRepository r : transportRepositories){
for(TransportIndexRepository r : transportRepositories.values()){
r.close();
}
transportRepositories.clear();
@ -939,7 +971,6 @@ public class ResourceManager {
imagesOnFS.clear();
indexFileNames.clear();
basemapFileNames.clear();
liveUpdatesFiles.clear();
renderer.clearAllResources();
closeAmenities();
closeRouteFiles();
@ -971,9 +1002,6 @@ public class ResourceManager {
return new LinkedHashMap<String, String>(indexFileNames);
}
public Map<String, String> getLiveIndexFileNames() {
return new LinkedHashMap<String, String>(liveUpdatesFiles);
}
public boolean containsBasemap(){
return !basemapFileNames.isEmpty();
@ -1027,4 +1055,8 @@ public class ResourceManager {
cacheOfImages.remove(list.get(i));
}
}
public IncrementalChangesManager getChangesManager() {
return changesManager;
}
}