initial import
git-svn-id: https://osmand.googlecode.com/svn/trunk@3 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
24df06a387
commit
2b43c07373
27 changed files with 2002 additions and 0 deletions
7
BatteryLifeLog/.classpath
Normal file
7
BatteryLifeLog/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
33
BatteryLifeLog/.project
Normal file
33
BatteryLifeLog/.project
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>BatteryLifeLog</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
34
BatteryLifeLog/AndroidManifest.xml
Normal file
34
BatteryLifeLog/AndroidManifest.xml
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.anvisics.battery"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS"></uses-permission>
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||
<activity android:name=".BatteryViewActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:permission="android.permission.BATTERY_STATS" android:process="@string/batter_name_service" android:label="@string/batter_name_service" android:name=".BatteryLogService">
|
||||
<intent-filter><action android:name="com.anvisics.BatteryLogService"></action>
|
||||
</intent-filter>
|
||||
</service>
|
||||
<receiver android:name=".BatteryStatusReceiver">
|
||||
<intent-filter><action android:name="android.intent.action.BATTERY_CHANGED"></action>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_OWNER_DATA"></uses-permission>
|
||||
<uses-permission android:name="android.permission.READ_OWNER_DATA"></uses-permission>
|
||||
</manifest>
|
13
BatteryLifeLog/default.properties
Normal file
13
BatteryLifeLog/default.properties
Normal file
|
@ -0,0 +1,13 @@
|
|||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Indicates whether an apk should be generated for each density.
|
||||
split.density=false
|
||||
# Project target.
|
||||
target=android-3
|
42
BatteryLifeLog/gen/com/anvisics/battery/R.java
Normal file
42
BatteryLifeLog/gen/com/anvisics/battery/R.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||||
*
|
||||
* This class was automatically generated by the
|
||||
* aapt tool from the resource data it found. It
|
||||
* should not be modified by hand.
|
||||
*/
|
||||
|
||||
package com.anvisics.battery;
|
||||
|
||||
public final class R {
|
||||
public static final class attr {
|
||||
}
|
||||
public static final class color {
|
||||
public static final int background=0x7f050000;
|
||||
}
|
||||
public static final class drawable {
|
||||
public static final int icon=0x7f020000;
|
||||
}
|
||||
public static final class id {
|
||||
public static final int Button01=0x7f070001;
|
||||
public static final int Button02=0x7f070002;
|
||||
public static final int Clear=0x7f070005;
|
||||
public static final int Exit=0x7f070004;
|
||||
public static final int Export=0x7f070006;
|
||||
public static final int GridView01=0x7f070003;
|
||||
public static final int LinearLayout01=0x7f070000;
|
||||
}
|
||||
public static final class layout {
|
||||
public static final int main=0x7f030000;
|
||||
public static final int mytext=0x7f030001;
|
||||
}
|
||||
public static final class menu {
|
||||
public static final int main_menu=0x7f060000;
|
||||
}
|
||||
public static final class string {
|
||||
public static final int app_name=0x7f040001;
|
||||
public static final int batter_name_service=0x7f040004;
|
||||
public static final int hello=0x7f040000;
|
||||
public static final int start_service=0x7f040002;
|
||||
public static final int stop_service=0x7f040003;
|
||||
}
|
||||
}
|
BIN
BatteryLifeLog/res/drawable/icon.png
Normal file
BIN
BatteryLifeLog/res/drawable/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
24
BatteryLifeLog/res/layout/main.xml
Normal file
24
BatteryLifeLog/res/layout/main.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
|
||||
<LinearLayout android:orientation="horizontal" android:id="@+id/LinearLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||
<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/start_service">
|
||||
</Button>
|
||||
|
||||
<Button android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/stop_service"></Button>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
<GridView android:id="@+id/GridView01" android:layout_width="wrap_content" android:layout_height="fill_parent" android:smoothScrollbar="true" android:numColumns="auto_fit" android:focusable="false">
|
||||
|
||||
</GridView>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
6
BatteryLifeLog/res/layout/mytext.xml
Normal file
6
BatteryLifeLog/res/layout/mytext.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</TextView>
|
8
BatteryLifeLog/res/menu/main_menu.xml
Normal file
8
BatteryLifeLog/res/menu/main_menu.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/Exit" android:title="Exit" android:orderInCategory="2"></item>
|
||||
<item android:menuCategory="container" android:title="Clear All" android:alphabeticShortcut="A" android:id="@+id/Clear" android:orderInCategory="1"></item>
|
||||
|
||||
<item android:id="@+id/Export" android:title="Export To File"></item>
|
||||
</menu>
|
9
BatteryLifeLog/res/values/strings.xml
Normal file
9
BatteryLifeLog/res/values/strings.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="hello">Hello World, BatteryViewActivity!</string>
|
||||
<string name="app_name">BatteryLifeLog</string>
|
||||
<string name="start_service">Запустить сервис</string>
|
||||
<string name="stop_service">Остановить сервис</string>
|
||||
<color name="background">#FFFFFF</color>
|
||||
<string name="batter_name_service">Batter Log service</string>
|
||||
</resources>
|
158
BatteryLifeLog/src/com/anvisics/battery/BatteryLogService.java
Normal file
158
BatteryLifeLog/src/com/anvisics/battery/BatteryLogService.java
Normal file
|
@ -0,0 +1,158 @@
|
|||
package com.anvisics.battery;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.text.format.DateFormat;
|
||||
|
||||
public class BatteryLogService extends Service {
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return binder;
|
||||
}
|
||||
|
||||
|
||||
private BatteryLogBinder binder = new BatteryLogBinder();
|
||||
private BatteryStatusReceiver batteryStatusReceiver;
|
||||
|
||||
|
||||
public static class BatteryLogEntry {
|
||||
private int batteryLevel;
|
||||
private int batteryVoltage;
|
||||
private long time;
|
||||
private int plugged;
|
||||
private int status;
|
||||
|
||||
|
||||
public BatteryLogEntry(){
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public int getPlugged() {
|
||||
return plugged;
|
||||
}
|
||||
public void setPlugged(int plugged) {
|
||||
this.plugged = plugged;
|
||||
}
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
public int getBatteryLevel() {
|
||||
return batteryLevel;
|
||||
}
|
||||
public void setBatteryLevel(int batteryLevel) {
|
||||
this.batteryLevel = batteryLevel;
|
||||
}
|
||||
public int getBatteryVoltage() {
|
||||
return batteryVoltage;
|
||||
}
|
||||
public void setBatteryVoltage(int batteryVoltage) {
|
||||
this.batteryVoltage = batteryVoltage;
|
||||
}
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public boolean sameMeasurements(BatteryLogEntry e ){
|
||||
return batteryLevel == e.batteryLevel &&
|
||||
batteryVoltage == e.batteryVoltage &&
|
||||
status == e.status &&
|
||||
plugged == e.plugged;
|
||||
}
|
||||
|
||||
public String getMessage(){
|
||||
String statusS = "";
|
||||
switch(status){
|
||||
case BatteryManager.BATTERY_STATUS_CHARGING : statusS = "CHARGING";
|
||||
case BatteryManager.BATTERY_STATUS_DISCHARGING: statusS = "DISCHARGING";
|
||||
case BatteryManager.BATTERY_STATUS_FULL: statusS = "FULL";
|
||||
case BatteryManager.BATTERY_STATUS_NOT_CHARGING: statusS = "NOT_CHARGING";
|
||||
}
|
||||
String pluggedS = "";
|
||||
switch(plugged){
|
||||
case BatteryManager.BATTERY_PLUGGED_AC: pluggedS = "PLUGGED_AC";
|
||||
case BatteryManager.BATTERY_PLUGGED_USB: pluggedS = "PLUGGED_USB";
|
||||
}
|
||||
CharSequence timeS = DateFormat.format("MM/dd/yy k:mm",this.time);
|
||||
return MessageFormat.format("{0} : battery ({1}), voltage ({2}), plugged ({3}), status ({4})",
|
||||
timeS, batteryLevel, batteryVoltage, pluggedS, statusS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class BatteryLogBinder extends Binder {
|
||||
|
||||
private List<BatteryLogEntry> entries = new ArrayList<BatteryLogEntry>();
|
||||
|
||||
|
||||
public boolean addEntry(BatteryLogEntry e){
|
||||
if(entries.isEmpty()){
|
||||
entries.add(e);
|
||||
return true;
|
||||
}
|
||||
BatteryLogEntry last = entries.get(entries.size() - 1);
|
||||
if(!last.sameMeasurements(e) || e.getTime() - last.getTime() > 60000){
|
||||
entries.add(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void clearEntries(){
|
||||
entries.clear();
|
||||
}
|
||||
public List<BatteryLogEntry> getEntries() {
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
batteryStatusReceiver = new BatteryStatusReceiver(this);
|
||||
registerReceiver(batteryStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||
|
||||
receiveMessage(100, 0, 0, 1);
|
||||
}
|
||||
|
||||
public void receiveMessage(int voltage, int level, int plugged, int status){
|
||||
BatteryLogEntry entry = new BatteryLogEntry();
|
||||
entry.setBatteryVoltage(voltage);
|
||||
entry.setBatteryLevel(level);
|
||||
entry.setPlugged(plugged);
|
||||
entry.setStatus(status);
|
||||
binder.addEntry(entry);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
unregisterReceiver(batteryStatusReceiver);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.anvisics.battery;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class BatteryStatusReceiver extends BroadcastReceiver {
|
||||
|
||||
private final BatteryLogService service;
|
||||
|
||||
public BatteryStatusReceiver(BatteryLogService service){
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
service.receiveMessage(intent.getIntExtra("voltage", -1), intent.getIntExtra("level", -1),
|
||||
intent.getIntExtra("plugged", -1), intent.getIntExtra("status", -1));
|
||||
|
||||
}
|
||||
|
||||
}
|
177
BatteryLifeLog/src/com/anvisics/battery/BatteryViewActivity.java
Normal file
177
BatteryLifeLog/src/com/anvisics/battery/BatteryViewActivity.java
Normal file
|
@ -0,0 +1,177 @@
|
|||
package com.anvisics.battery;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.GridView;
|
||||
|
||||
import com.anvisics.battery.BatteryLogService.BatteryLogBinder;
|
||||
import com.anvisics.battery.BatteryLogService.BatteryLogEntry;
|
||||
|
||||
public class BatteryViewActivity extends Activity {
|
||||
private Button startServiceButton;
|
||||
private Button stopServiceButton;
|
||||
private GridView gridView;
|
||||
|
||||
|
||||
private final Intent serviceIntent = new Intent("com.anvisics.BatteryLogService");
|
||||
|
||||
ServiceConnection serviceConnection = null;
|
||||
private ArrayAdapter<BatteryLogEntry> gridViewAdapter;
|
||||
private BatteryLogBinder binder = null;
|
||||
|
||||
private class MyServiceConnection implements ServiceConnection {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
if(service instanceof BatteryLogBinder){
|
||||
gridViewAdapter.clear();
|
||||
binder = (BatteryLogBinder) service;
|
||||
List<BatteryLogEntry> entries = ((BatteryLogBinder) service).getEntries();
|
||||
for(int i = entries.size() - 1; i>=0; i--){
|
||||
gridViewAdapter.add(entries.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
gridViewAdapter.clear();
|
||||
binder = null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
|
||||
startServiceButton = (Button)findViewById(R.id.Button01);
|
||||
stopServiceButton = (Button)findViewById(R.id.Button02);
|
||||
|
||||
|
||||
|
||||
gridView = (GridView) findViewById(R.id.GridView01);
|
||||
|
||||
gridView.setNumColumns(1);
|
||||
gridView.setVerticalSpacing(3);
|
||||
gridViewAdapter = new ArrayAdapter<BatteryLogEntry>(getWindow().getContext(), R.layout.mytext);
|
||||
gridView.setAdapter(gridViewAdapter);
|
||||
|
||||
|
||||
startServiceButton.setOnClickListener(new OnClickListener(){
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ComponentName name = getWindow().getContext().startService(serviceIntent);
|
||||
if(name != null){
|
||||
stopServiceButton.setEnabled(true);
|
||||
startServiceButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
stopServiceButton.setOnClickListener(new OnClickListener(){
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
boolean stopService = getWindow().getContext().stopService(serviceIntent);
|
||||
if(stopService){
|
||||
stopServiceButton.setEnabled(false);
|
||||
startServiceButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ComponentName componentName = getWindow().getContext().startService(serviceIntent);
|
||||
startServiceButton.setEnabled(componentName == null);
|
||||
stopServiceButton.setEnabled(componentName != null);
|
||||
serviceConnection = new MyServiceConnection();
|
||||
|
||||
|
||||
getWindow().getContext().bindService(serviceIntent, serviceConnection, 0);
|
||||
|
||||
}
|
||||
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.main_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if(item.getItemId() == R.id.Clear){
|
||||
if(binder != null){
|
||||
binder.clearEntries();
|
||||
gridViewAdapter.clear();
|
||||
}
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.Export) {
|
||||
if (binder == null) {
|
||||
return true;
|
||||
}
|
||||
File directory = Environment.getExternalStorageDirectory();
|
||||
if (directory.canWrite()) {
|
||||
File f = new File(directory, "BatteryLog.txt");
|
||||
int i = 1;
|
||||
while (f.exists()) {
|
||||
f = new File(directory, "BatteryLog" + (++i) + ".txt");
|
||||
}
|
||||
|
||||
try {
|
||||
BufferedWriter writer = new BufferedWriter(
|
||||
new FileWriter(f));
|
||||
List<BatteryLogEntry> entries = binder.getEntries();
|
||||
for (i = entries.size() - 1; i >= 0; i--) {
|
||||
writer.write(entries.get(i).toString());
|
||||
}
|
||||
writer.close();
|
||||
binder.clearEntries();
|
||||
gridViewAdapter.clear();
|
||||
} catch (IOException e) {
|
||||
Log.e("batteryLog", "Can't export file", e);
|
||||
}
|
||||
}
|
||||
} else if(item.getItemId() == R.id.Exit){
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(serviceConnection != null){
|
||||
getWindow().getContext().unbindService(serviceConnection);
|
||||
serviceConnection = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
9
DataExtractionOSM/.classpath
Normal file
9
DataExtractionOSM/.classpath
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/bzip2-20090327.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-logging-1.1.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/osmosis-0.32.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
17
DataExtractionOSM/.project
Normal file
17
DataExtractionOSM/.project
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>DataExtractionOSM</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
BIN
DataExtractionOSM/lib/bzip2-20090327.jar
Normal file
BIN
DataExtractionOSM/lib/bzip2-20090327.jar
Normal file
Binary file not shown.
BIN
DataExtractionOSM/lib/commons-logging-1.1.1.jar
Normal file
BIN
DataExtractionOSM/lib/commons-logging-1.1.1.jar
Normal file
Binary file not shown.
BIN
DataExtractionOSM/lib/jpf.jar
Normal file
BIN
DataExtractionOSM/lib/jpf.jar
Normal file
Binary file not shown.
BIN
DataExtractionOSM/lib/osmosis-0.32.jar
Normal file
BIN
DataExtractionOSM/lib/osmosis-0.32.jar
Normal file
Binary file not shown.
10
DataExtractionOSM/src/com/anvisics/Constants.java
Normal file
10
DataExtractionOSM/src/com/anvisics/Constants.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package com.anvisics;
|
||||
|
||||
public interface Constants {
|
||||
|
||||
// TODO externalize proper way
|
||||
public String pathToTestDataDir = "E:\\Information\\gps\\OpenMap\\";
|
||||
|
||||
public String ADDR_HOUSE_NUMBER = "addr:housenumber";
|
||||
public String ADDR_STREET = "addr:street";
|
||||
}
|
528
DataExtractionOSM/src/com/anvisics/DataExtraction.java
Normal file
528
DataExtractionOSM/src/com/anvisics/DataExtraction.java
Normal file
|
@ -0,0 +1,528 @@
|
|||
package com.anvisics;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSplitPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.event.UndoableEditEvent;
|
||||
import javax.swing.event.UndoableEditListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
|
||||
import org.apache.tools.bzip2.CBZip2InputStream;
|
||||
import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer;
|
||||
import org.openstreetmap.osmosis.core.container.v0_6.NodeContainer;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Node;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Tag;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Way;
|
||||
import org.openstreetmap.osmosis.core.task.v0_6.Sink;
|
||||
import org.openstreetmap.osmosis.core.xml.v0_6.impl.OsmHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.anvisics.MapPanel.IMapLocationListener;
|
||||
import com.anvisics.NodeUtil.LatLon;
|
||||
import com.anvisics.data.City;
|
||||
import com.anvisics.data.Region;
|
||||
import com.anvisics.data.Street;
|
||||
import com.anvisics.data.City.CityType;
|
||||
|
||||
|
||||
// TO implement
|
||||
// 1. Full structured search for town/street/building.
|
||||
|
||||
/**
|
||||
* http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing#Is_inside.2Foutside
|
||||
* http://wiki.openstreetmap.org/wiki/Relations/Proposed/Postal_Addresses
|
||||
* http://wiki.openstreetmap.org/wiki/Proposed_features/House_numbers/Karlsruhe_Schema#Tags (node, way)
|
||||
*
|
||||
* 1. node - place : country, state, region, county, city, town, village, hamlet, suburb
|
||||
* That node means label for place ! It is widely used in OSM.
|
||||
*
|
||||
* 2. way - highway : primary, secondary, service.
|
||||
* That node means label for street if it is in city (primary, secondary, residential, tertiary, living_street),
|
||||
* beware sometimes that roads could outside city. Usage : often
|
||||
*
|
||||
* outside city : trunk, motorway, motorway_link...
|
||||
* special tags : lanes - 3, maxspeed - 90, bridge
|
||||
*
|
||||
* 3. relation - type = address. address:type : country, a1, a2, a3, a4, a5, a6, ... hno.
|
||||
* member:node role=label :
|
||||
* member:relation role=border :
|
||||
* member:node role=a1,a2... :
|
||||
*
|
||||
* 4. node, way - addr:housenumber(+), addr:street(+), addr:country(+/-), addr:city(-)
|
||||
* building=yes
|
||||
*
|
||||
* 5. relation - boundary=administrative, admin_level : 1, 2, ....
|
||||
*
|
||||
* 6. node, way - addr:postcode =?
|
||||
* relation - type=postal_code (members way, node), postal_code=?
|
||||
*
|
||||
* 7. node, way - amenity=?
|
||||
*
|
||||
*/
|
||||
public class DataExtraction implements IMapLocationListener {
|
||||
|
||||
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XMLStreamException {
|
||||
new DataExtraction().testReadingOsmFile();
|
||||
}
|
||||
|
||||
|
||||
private static boolean parseMinsk = true;
|
||||
private static boolean parseOSM = true;
|
||||
|
||||
///////////////////////////////////////////
|
||||
// 1. Reading data - preparing data for UI
|
||||
public void testReadingOsmFile() throws ParserConfigurationException, SAXException, IOException, XMLStreamException {
|
||||
|
||||
InputStream stream ;
|
||||
if(parseMinsk){
|
||||
stream = new FileInputStream(Constants.pathToTestDataDir+"minsk_old.osm");
|
||||
} else {
|
||||
// stream = new FileInputStream(Constants.pathToTestDataDir+"belarus_2010_04_01.osm.bz2");
|
||||
// stream = new FileInputStream(Constants.pathToTestDataDir+"minsk_old.osm");
|
||||
stream = new FileInputStream(Constants.pathToTestDataDir+"minsk_2010_04_26.osm.bz2");
|
||||
if (stream.read() != 66 || stream.read() != 90)
|
||||
throw new RuntimeException(
|
||||
"The source stream must start with the characters BZ if it is to be read as a BZip2 stream.");
|
||||
else
|
||||
stream = new CBZip2InputStream(stream);
|
||||
}
|
||||
|
||||
|
||||
System.out.println("USED Memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1e6);
|
||||
long st = System.currentTimeMillis();
|
||||
|
||||
|
||||
// preloaded data
|
||||
final List<Node> places = new ArrayList<Node>();
|
||||
final Map<Long, LatLon> nodes = new HashMap<Long, LatLon>();
|
||||
final List<Entity> buildings = new ArrayList<Entity>();
|
||||
final List<Node> amenities = new ArrayList<Node>();
|
||||
|
||||
|
||||
// highways count
|
||||
final Map<String, Integer> mapWays = new LinkedHashMap<String, Integer>();
|
||||
|
||||
if (parseOSM) {
|
||||
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
|
||||
parser.parse(stream, new OsmHandler(new Sink() {
|
||||
@Override
|
||||
public void process(EntityContainer entityContainer) {
|
||||
if (entityContainer instanceof NodeContainer) {
|
||||
NodeContainer rc = (NodeContainer) entityContainer;
|
||||
if (NodeUtil.getTag(rc.getEntity(), "place") != null) {
|
||||
places.add(rc.getEntity());
|
||||
if (places.size() % 500 == 0) {
|
||||
System.out.println();
|
||||
}
|
||||
System.out.print("-");
|
||||
}
|
||||
nodes.put(rc.getEntity().getId(), new LatLon(rc.getEntity().getLatitude(),
|
||||
rc.getEntity().getLongitude()));
|
||||
if (NodeUtil.getTag(entityContainer.getEntity(), "amenity") != null) {
|
||||
amenities.add((Node) entityContainer.getEntity());
|
||||
} else if (NodeUtil.getTag(entityContainer.getEntity(), "shop") != null) {
|
||||
Entity n = entityContainer.getEntity();
|
||||
n.getTags().add(new Tag("amenity", "shop"));
|
||||
amenities.add((Node) n);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
if (NodeUtil.tag(entityContainer.getEntity(), "building", "yes")) {
|
||||
Entity e = entityContainer.getEntity();
|
||||
if (NodeUtil.getTag(e, Constants.ADDR_HOUSE_NUMBER) != null
|
||||
&& NodeUtil.getTag(e, Constants.ADDR_STREET) != null) {
|
||||
buildings.add(e);
|
||||
}
|
||||
}
|
||||
if (NodeUtil.getTag(entityContainer.getEntity(), "highway") != null) {
|
||||
String h = NodeUtil.getTag(entityContainer.getEntity(), "highway");
|
||||
if(!mapWays.containsKey(h)){
|
||||
mapWays.put(h, 0);
|
||||
}
|
||||
mapWays.put(h, mapWays.get(h) + 1);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
}
|
||||
}, false));
|
||||
}
|
||||
|
||||
System.out.println("\n"+mapWays);
|
||||
System.out.println(System.currentTimeMillis() - st);
|
||||
|
||||
// 1. found towns !
|
||||
Region country = new Region(null);
|
||||
for (Node s : places) {
|
||||
String place = NodeUtil.getTag(s, "place");
|
||||
if(place == null){
|
||||
continue;
|
||||
}
|
||||
if("country".equals(place)){
|
||||
country.setEntity(s);
|
||||
} else {
|
||||
City registerCity = country.registerCity(s);
|
||||
if(registerCity == null){
|
||||
System.out.println(place + " - " + NodeUtil.getTag(s, "name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. found buildings (index addresses)
|
||||
for(Entity b : buildings){
|
||||
LatLon center ;
|
||||
if(b instanceof Node){
|
||||
center = NodeUtil.getLatLon((Node) b);
|
||||
} else {
|
||||
center = NodeUtil.getWeightCenter((Way) b, nodes);
|
||||
}
|
||||
// TODO first of all tag could be checked NodeUtil.getTag(e, "addr:city")
|
||||
City city = country.getClosestCity(center);
|
||||
if(city != null){
|
||||
city.registerBuilding(center, b);
|
||||
}
|
||||
}
|
||||
|
||||
for(Node node : amenities){
|
||||
country.registerAmenity(node);
|
||||
}
|
||||
|
||||
|
||||
runUI(country);
|
||||
|
||||
System.out.println();
|
||||
System.out.println("USED Memory " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1e6);
|
||||
System.out.println("TIME : " + (System.currentTimeMillis() - st));
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// 2. Showing UI
|
||||
|
||||
protected City selectedCity;
|
||||
|
||||
private MapPanel mapPanel = new MapPanel(new File(Constants.pathToTestDataDir+"MinskTiles"));
|
||||
|
||||
private DefaultMutableTreeNode amenitiesTree;
|
||||
private JTree treePlaces;
|
||||
|
||||
public void runUI(final Region r){
|
||||
JFrame frame = new JFrame("Tree of choose");
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
DefaultMutableTreeNode root = new DataExtractionTreeNode(r.getName(), r);
|
||||
amenitiesTree = new DataExtractionTreeNode("Amenities", r);
|
||||
amenitiesTree.add(new DataExtractionTreeNode("closest", r));
|
||||
root.add(amenitiesTree);
|
||||
for(CityType t : CityType.values()){
|
||||
DefaultMutableTreeNode cityTree = new DataExtractionTreeNode(t.toString(), t);
|
||||
root.add(cityTree);
|
||||
for(City ct : r.getCitiesByType(t)){
|
||||
DefaultMutableTreeNode cityNodeTree = new DataExtractionTreeNode(ct.getName(), ct);
|
||||
cityTree.add(cityNodeTree);
|
||||
|
||||
for(Street str : ct.getStreets()){
|
||||
DefaultMutableTreeNode strTree = new DataExtractionTreeNode(str.getName(), str);
|
||||
cityNodeTree.add(strTree);
|
||||
for(Entity e : str.getBuildings()){
|
||||
DefaultMutableTreeNode building = new DataExtractionTreeNode(NodeUtil.getTag(e, Constants.ADDR_HOUSE_NUMBER), e);
|
||||
strTree.add(building);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
frame.addWindowListener(new ExitListener());
|
||||
Container content = frame.getContentPane();
|
||||
frame.setFocusable(true);
|
||||
|
||||
|
||||
treePlaces = new JTree(root);
|
||||
final JList jList = new JList();
|
||||
jList.setCellRenderer(new DefaultListCellRenderer(){
|
||||
private static final long serialVersionUID = 4661949460526837891L;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list,
|
||||
Object value, int index, boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
super.getListCellRendererComponent(list, value, index, isSelected,
|
||||
cellHasFocus);
|
||||
if(value instanceof City){
|
||||
setText(((City)value).getName());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
JSplitPane panelForTreeAndImage = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(treePlaces), mapPanel);
|
||||
panelForTreeAndImage.setResizeWeight(0.2);
|
||||
mapPanel.setFocusable(true);
|
||||
mapPanel.addMapLocationListener(this);
|
||||
|
||||
|
||||
|
||||
JSplitPane pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(jList), panelForTreeAndImage);
|
||||
pane.setResizeWeight(0.2);
|
||||
content.add(pane, BorderLayout.CENTER);
|
||||
|
||||
final JLabel label = new JLabel();
|
||||
content.add(label, BorderLayout.SOUTH);
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
final JTextField textField = new JTextField();
|
||||
final JButton button = new JButton();
|
||||
button.setText("Set town");
|
||||
panel.add(textField, BorderLayout.CENTER);
|
||||
panel.add(button, BorderLayout.EAST);
|
||||
|
||||
content.add(panel, BorderLayout.NORTH);
|
||||
|
||||
|
||||
updateListCities(r, textField.getText(), jList);
|
||||
textField.getDocument().addUndoableEditListener(new UndoableEditListener(){
|
||||
@Override
|
||||
public void undoableEditHappened(UndoableEditEvent e) {
|
||||
updateListCities(r, textField.getText(), jList);
|
||||
}
|
||||
});
|
||||
|
||||
button.addActionListener(new ActionListener(){
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
selectedCity = (City)jList.getSelectedValue();
|
||||
}
|
||||
});
|
||||
|
||||
jList.addListSelectionListener(new ListSelectionListener(){
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if(jList.getSelectedValue() != null){
|
||||
Node node = ((City)jList.getSelectedValue()).getNode();
|
||||
String text = "Lat : " + node.getLatitude() + " Lon " + node.getLongitude();
|
||||
if(selectedCity != null){
|
||||
text += " distance " + NodeUtil.getDistance(selectedCity.getNode(), node);
|
||||
}
|
||||
label.setText(text);
|
||||
mapPanel.setLatLon(node.getLatitude(), node.getLongitude());
|
||||
} else {
|
||||
String text = selectedCity == null ? "" : selectedCity.getName();
|
||||
label.setText(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
treePlaces.addTreeSelectionListener(new TreeSelectionListener(){
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
if (e.getPath() != null) {
|
||||
if (e.getPath().getLastPathComponent() instanceof DefaultMutableTreeNode) {
|
||||
Object o = ((DefaultMutableTreeNode) e.getPath().getLastPathComponent()).getUserObject();
|
||||
|
||||
if (o instanceof City) {
|
||||
City c = (City) o;
|
||||
mapPanel.setLatLon(c.getNode().getLatitude(), c.getNode().getLongitude());
|
||||
mapPanel.requestFocus();
|
||||
}
|
||||
|
||||
if (o instanceof Entity) {
|
||||
Entity c = (Entity) o;
|
||||
if (c instanceof Node) {
|
||||
mapPanel.setLatLon(((Node) c).getLatitude(), ((Node) c).getLongitude());
|
||||
// mapPanel.requestFocus();
|
||||
} else {
|
||||
DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.getPath().getPathComponent(
|
||||
e.getPath().getPathCount() - 2);
|
||||
if (n.getUserObject() instanceof Street) {
|
||||
Street str = (Street) n.getUserObject();
|
||||
LatLon l = str.getLocationBuilding(c);
|
||||
mapPanel.setLatLon(l.getLatitude(), l.getLongitude());
|
||||
mapPanel.requestFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
frame.setSize(1024, 768);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void locationChanged(final double newLatitude, final double newLongitude){
|
||||
Region reg = (Region) amenitiesTree.getUserObject();
|
||||
List<Node> closestAmenities = reg.getClosestAmenities(newLatitude, newLongitude);
|
||||
Collections.sort(closestAmenities, new Comparator<Node>(){
|
||||
@Override
|
||||
public int compare(Node o1, Node o2) {
|
||||
return Double.compare(NodeUtil.getDistance(o1, newLatitude, newLongitude),
|
||||
NodeUtil.getDistance(o2, newLatitude, newLongitude));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Map<String, List<Node>> filter = new TreeMap<String, List<Node>>();
|
||||
for(Node n : closestAmenities){
|
||||
String type = NodeUtil.getTag(n, "amenity");
|
||||
if(!filter.containsKey(type)){
|
||||
filter.put(type, new ArrayList<Node>());
|
||||
}
|
||||
filter.get(type).add(n);
|
||||
}
|
||||
for(int i=1; i< amenitiesTree.getChildCount(); ){
|
||||
if(!filter.containsKey(((DefaultMutableTreeNode)amenitiesTree.getChildAt(i)).getUserObject())){
|
||||
amenitiesTree.remove(i);
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
((DefaultMutableTreeNode)amenitiesTree.getChildAt(0)).removeAllChildren();
|
||||
|
||||
|
||||
for(int i=0; i<15 && i < closestAmenities.size(); i++){
|
||||
Node n = closestAmenities.get(i);
|
||||
String type = NodeUtil.getTag(n, "amenity");
|
||||
String name = NodeUtil.getTag(n, "name");
|
||||
int dist = (int) (NodeUtil.getDistance(n, newLatitude, newLongitude));
|
||||
String str = type +" "+(name == null ? n.getId() : name) +" [" +dist+" m ]";
|
||||
((DefaultMutableTreeNode)amenitiesTree.getChildAt(0)).add(
|
||||
new DataExtractionTreeNode(str, n));
|
||||
}
|
||||
|
||||
for(String s : filter.keySet()){
|
||||
DefaultMutableTreeNode p = null;
|
||||
for(int i=0; i< amenitiesTree.getChildCount(); i++){
|
||||
if(s.equals(((DefaultMutableTreeNode)amenitiesTree.getChildAt(i)).getUserObject())){
|
||||
p = ((DefaultMutableTreeNode)amenitiesTree.getChildAt(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p == null) {
|
||||
p = new DefaultMutableTreeNode(s);
|
||||
}
|
||||
// Map<Node, DataExtractionTreeNode> consists = new LinkedHashMap<Node, DataExtractionTreeNode>();
|
||||
// for(Node n : filter.get(s)){
|
||||
// consists.put(n, null);
|
||||
// }
|
||||
// for(int i=0; i<p.getChildCount();){
|
||||
// Object userObject = ((DefaultMutableTreeNode)p.getChildAt(i)).getUserObject();
|
||||
// if(consists.containsKey(userObject)){
|
||||
// consists.put((Node) userObject, (DataExtractionTreeNode) p.getChildAt(i));
|
||||
// i++;
|
||||
// } else {
|
||||
// p.remove(i);
|
||||
// }
|
||||
// }
|
||||
|
||||
p.removeAllChildren();
|
||||
for(Node n : filter.get(s)){
|
||||
String name = NodeUtil.getTag(n, "name");
|
||||
int dist = (int) (NodeUtil.getDistance(n, newLatitude, newLongitude));
|
||||
String str = (name == null ? n.getId() : name) +" [" +dist+" m ]";
|
||||
// if(consists.get(n) != null){
|
||||
// consists.get(n).setName(str);
|
||||
// } else {
|
||||
DataExtractionTreeNode node = new DataExtractionTreeNode(str, n);
|
||||
p.add(node);
|
||||
// }
|
||||
}
|
||||
amenitiesTree.add(p);
|
||||
}
|
||||
treePlaces.updateUI();
|
||||
}
|
||||
|
||||
public void updateListCities(Region r, String text, JList jList){
|
||||
Collection<City> city = r.getSuggestedCities(text, 100);
|
||||
City[] names = new City[city.size()];
|
||||
int i=0;
|
||||
for(City c : city){
|
||||
names[i++] = c;
|
||||
}
|
||||
jList.setListData(names);
|
||||
}
|
||||
|
||||
|
||||
public static class DataExtractionTreeNode extends DefaultMutableTreeNode {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String name;
|
||||
|
||||
public DataExtractionTreeNode(String name, Object userObject){
|
||||
super(userObject);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
public static class ExitListener extends WindowAdapter {
|
||||
public void windowClosing(WindowEvent event) {
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
335
DataExtractionOSM/src/com/anvisics/MapPanel.java
Normal file
335
DataExtractionOSM/src/com/anvisics/MapPanel.java
Normal file
|
@ -0,0 +1,335 @@
|
|||
package com.anvisics;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import com.anvisics.DataExtraction.ExitListener;
|
||||
|
||||
public class MapPanel extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public interface IMapLocationListener {
|
||||
void locationChanged(double newLatitude, double newLongitude);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
JFrame frame = new JFrame("Tree of choose");
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
frame.addWindowListener(new ExitListener());
|
||||
Container content = frame.getContentPane();
|
||||
|
||||
// MapPanel panel = new MapPanel(new ZipFile(Constants.pathToTestDataDir + "MinskTiles.zipp"));
|
||||
MapPanel panel = new MapPanel(new File(Constants.pathToTestDataDir + "MinskTiles"));
|
||||
|
||||
content.add(panel, BorderLayout.CENTER);
|
||||
|
||||
frame.setSize(512, 512);
|
||||
frame.setVisible(true);
|
||||
|
||||
}
|
||||
|
||||
private final int tileSize = 256;
|
||||
private BufferedImage[][] images;
|
||||
private int xStartingImage = 0;
|
||||
private int yStartingImage = 0;
|
||||
|
||||
private final File fileWithTiles;
|
||||
private int zoom = 15;
|
||||
|
||||
// degree measurements (-180, 180)
|
||||
// äîëãîòà
|
||||
private double longitude = 27.56;
|
||||
// øèðîòà
|
||||
// degree measurements (90, -90)
|
||||
private double latitude = 53.9;
|
||||
|
||||
private List<IMapLocationListener> listeners = new ArrayList<IMapLocationListener>();
|
||||
|
||||
private String map = "Mapnik";
|
||||
|
||||
public MapPanel(File fileWithTiles) {
|
||||
this.fileWithTiles = fileWithTiles;
|
||||
initUI();
|
||||
}
|
||||
|
||||
|
||||
public double getXTile(){
|
||||
return NodeUtil.getTileNumberX(zoom, longitude);
|
||||
}
|
||||
|
||||
public double getYTile(){
|
||||
return NodeUtil.getTileNumberY(zoom, latitude);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
System.out.println("draw");
|
||||
if (images != null) {
|
||||
for (int i = 0; i < images.length; i++) {
|
||||
for (int j = 0; j < images[i].length; j++) {
|
||||
if(images[i][j] == null){
|
||||
if((i+j + (int)getXTile() + (int)getYTile()) % 2 == 0){
|
||||
g.setColor(Color.gray);
|
||||
} else {
|
||||
g.setColor(Color.white);
|
||||
}
|
||||
g.fillRect(i * tileSize+xStartingImage, j * tileSize + yStartingImage, tileSize, tileSize);
|
||||
} else {
|
||||
g.drawImage(images[i][j], i * tileSize+xStartingImage, j * tileSize + yStartingImage, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
g.setColor(Color.black);
|
||||
|
||||
g.fillOval(getWidth()/2 - 2, getHeight()/2 -2, 4, 4);
|
||||
g.drawOval(getWidth()/2 - 2, getHeight()/2 -2, 4, 4);
|
||||
g.drawOval(getWidth()/2 - 5, getHeight()/2 -5, 10, 10);
|
||||
}
|
||||
|
||||
public String getFile(int x, int y){
|
||||
return map +"/"+zoom+"/"+(x) +"/"+y+".png";
|
||||
}
|
||||
|
||||
Map<String, BufferedImage> cache = new HashMap<String, BufferedImage>();
|
||||
public BufferedImage getImageFor(int x, int y) throws IOException{
|
||||
String file = getFile(x, y);
|
||||
if(!cache.containsKey(file)){
|
||||
// ZipEntry en = fileWithTiles.getEntry(file);
|
||||
File en = new File(fileWithTiles, file);
|
||||
if(cache.size() > 1000){
|
||||
ArrayList<String> list = new ArrayList<String>(cache.keySet());
|
||||
for(int i=0; i<list.size(); i+=2){
|
||||
cache.remove(list.get(i));
|
||||
}
|
||||
}
|
||||
// if(en != null){
|
||||
if(en.exists()){
|
||||
// cache.put(file, ImageIO.read(fileWithTiles.getInputStream(en)));
|
||||
long time = System.currentTimeMillis();
|
||||
cache.put(file, ImageIO.read(en));
|
||||
System.out.println("Loaded " + (System.currentTimeMillis() - time));
|
||||
} else {
|
||||
cache.put(file, null);
|
||||
}
|
||||
}
|
||||
|
||||
return cache.get(file);
|
||||
}
|
||||
|
||||
|
||||
// TODO async loading images (show busy cursor while it is loaded)
|
||||
public void prepareImage(){
|
||||
try {
|
||||
|
||||
if (images != null) {
|
||||
for (int i = 0; i < images.length; i++) {
|
||||
for (int j = 0; j < images[i].length; j++) {
|
||||
// dispose
|
||||
}
|
||||
}
|
||||
}
|
||||
double xTile = getXTile();
|
||||
double yTile = getYTile();
|
||||
double leftX = (getSize().width/2d - (xTile - Math.floor(xTile)) *tileSize)/tileSize;
|
||||
double leftY = (getSize().height/2d - (yTile - Math.floor(yTile)) *tileSize)/tileSize;
|
||||
|
||||
int xStartInd = (int) (Math.floor(xTile) - Math.ceil(leftX));
|
||||
int yStartInd = (int) (Math.floor(yTile) - Math.ceil(leftY));
|
||||
|
||||
xStartingImage = (int) ((leftX - Math.ceil(leftX))*tileSize);
|
||||
yStartingImage = (int) ((leftY - Math.ceil(leftY))*tileSize);
|
||||
|
||||
int tileXCount = (int) Math.ceil((getSize().width - xStartingImage)/ (double)tileSize );
|
||||
int tileYCount = (int) Math.ceil((getSize().height- yStartingImage)/ (double)tileSize );
|
||||
images = new BufferedImage[tileXCount][tileYCount];
|
||||
for(int i=0; i<images.length; i++){
|
||||
for(int j=0; j<images[i].length; j++){
|
||||
images[i][j]= getImageFor(xStartInd + i, yStartInd + j);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void initUI() {
|
||||
setFocusable(true);
|
||||
addComponentListener(new ComponentAdapter(){
|
||||
public void componentResized(ComponentEvent e) {
|
||||
prepareImage();
|
||||
}
|
||||
});
|
||||
MapMouseAdapter mouse = new MapMouseAdapter();
|
||||
addMouseListener(mouse);
|
||||
addMouseMotionListener(mouse);
|
||||
}
|
||||
|
||||
|
||||
public void setZoom(int zoom){
|
||||
this.zoom = zoom;
|
||||
prepareImage();
|
||||
}
|
||||
|
||||
public void setLatLon(double latitude, double longitude){
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
prepareImage();
|
||||
fireMapLocationListeners();
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public int getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
|
||||
public String getMap(){
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMapName(String map){
|
||||
this.map = map;
|
||||
prepareImage();
|
||||
}
|
||||
|
||||
public void addMapLocationListener(IMapLocationListener l){
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void removeMapLocationListener(IMapLocationListener l){
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
protected void fireMapLocationListeners(){
|
||||
for(IMapLocationListener l : listeners){
|
||||
l.locationChanged(latitude, longitude);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void processKeyEvent(KeyEvent e) {
|
||||
boolean processed = false;
|
||||
if (e.getID() == KeyEvent.KEY_RELEASED) {
|
||||
|
||||
if (e.getKeyCode() == 37) {
|
||||
longitude = NodeUtil.getLongitudeFromTile(zoom, getXTile()-0.5);
|
||||
processed = true;
|
||||
} else if (e.getKeyCode() == 39) {
|
||||
longitude = NodeUtil.getLongitudeFromTile(zoom, getXTile()+0.5);
|
||||
processed = true;
|
||||
} else if (e.getKeyCode() == 38) {
|
||||
latitude = NodeUtil.getLatitudeFromTile(zoom, getYTile()-0.5);
|
||||
processed = true;
|
||||
} else if (e.getKeyCode() == 40) {
|
||||
latitude = NodeUtil.getLatitudeFromTile(zoom, getYTile()+0.5);
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
if(e.getID() == KeyEvent.KEY_TYPED){
|
||||
if(e.getKeyChar() == '+'){
|
||||
zoom ++;
|
||||
processed = true;
|
||||
} else if(e.getKeyChar() == '-'){
|
||||
zoom --;
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(processed){
|
||||
e.consume();
|
||||
prepareImage();
|
||||
fireMapLocationListeners();
|
||||
}
|
||||
super.processKeyEvent(e);
|
||||
}
|
||||
|
||||
public class MapMouseAdapter extends MouseAdapter {
|
||||
private Point startDragging = null;
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if(e.getButton() == MouseEvent.BUTTON1){
|
||||
requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
public void dragTo(Point p){
|
||||
double dx = (startDragging.x - (double)p.x)/tileSize;
|
||||
double dy = (startDragging.y - (double)p.y)/tileSize;
|
||||
double lat = NodeUtil.getLatitudeFromTile(zoom, getYTile() + dy);
|
||||
double lon = NodeUtil.getLongitudeFromTile(zoom, getXTile() + dx);
|
||||
setLatLon(lat, lon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if(startDragging != null){
|
||||
if(Math.abs(e.getPoint().x - startDragging.x) + Math.abs(e.getPoint().y - startDragging.y) >= 8){
|
||||
dragTo(e.getPoint());
|
||||
startDragging = e.getPoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if(e.getButton() == MouseEvent.BUTTON3){
|
||||
if(startDragging == null){
|
||||
startDragging = e.getPoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if(e.getButton() == MouseEvent.BUTTON3){
|
||||
if(startDragging != null){
|
||||
dragTo(e.getPoint());
|
||||
fireMapLocationListeners();
|
||||
startDragging = null;
|
||||
}
|
||||
}
|
||||
super.mouseReleased(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
213
DataExtractionOSM/src/com/anvisics/NodeUtil.java
Normal file
213
DataExtractionOSM/src/com/anvisics/NodeUtil.java
Normal file
|
@ -0,0 +1,213 @@
|
|||
package com.anvisics;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Node;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Tag;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Way;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.WayNode;
|
||||
|
||||
public class NodeUtil {
|
||||
|
||||
public static class LatLon {
|
||||
private final double longitude;
|
||||
private final double latitude;
|
||||
|
||||
public LatLon(double latitude, double longitude){
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(latitude);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(longitude);
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LatLon other = (LatLon) obj;
|
||||
if (Double.doubleToLongBits(latitude) != Double
|
||||
.doubleToLongBits(other.latitude))
|
||||
return false;
|
||||
if (Double.doubleToLongBits(longitude) != Double
|
||||
.doubleToLongBits(other.longitude))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Lat " + latitude +" Lon "+ longitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static String getTag(Entity e, String name){
|
||||
for(Tag t : e.getTags()){
|
||||
if(name.equals(t.getKey())){
|
||||
return t.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static double getDistance(Node e1, Node e2){
|
||||
return getDistance(e1.getLatitude(), e1.getLongitude(), e2.getLatitude(), e2.getLongitude());
|
||||
}
|
||||
|
||||
public static double getDistance(Node e1, double latitude, double longitude){
|
||||
return getDistance(e1.getLatitude(), e1.getLongitude(), latitude, longitude);
|
||||
}
|
||||
|
||||
public static double getDistance(Node e1, LatLon point){
|
||||
return getDistance(e1.getLatitude(), e1.getLongitude(), point.getLatitude(), point.getLongitude());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets distance in meters
|
||||
*/
|
||||
public static double getDistance(double lat1, double lon1, double lat2, double lon2){
|
||||
double R = 6371; // km
|
||||
double dLat = Math.toRadians(lat2-lat1);
|
||||
double dLon = Math.toRadians(lon2-lon1);
|
||||
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
||||
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
|
||||
Math.sin(dLon/2) * Math.sin(dLon/2);
|
||||
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
||||
return R * c * 1000;
|
||||
}
|
||||
|
||||
public static LatLon getWeightCenter(Collection<LatLon> nodes){
|
||||
if(nodes.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
double longitude = 0;
|
||||
double latitude = 0;
|
||||
for(LatLon n : nodes){
|
||||
longitude += n.getLongitude();
|
||||
latitude += n.getLatitude();
|
||||
}
|
||||
return new LatLon(latitude/nodes.size(), longitude/nodes.size());
|
||||
}
|
||||
|
||||
public static LatLon getWeightCenterForNodes(Collection<Node> nodes){
|
||||
if(nodes.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
double longitude = 0;
|
||||
double latitude = 0;
|
||||
for(Node n : nodes){
|
||||
longitude += n.getLongitude();
|
||||
latitude += n.getLatitude();
|
||||
}
|
||||
return new LatLon(latitude/nodes.size(), longitude/nodes.size());
|
||||
}
|
||||
|
||||
public static LatLon getLatLon(Node n){
|
||||
return new LatLon(n.getLatitude(), n.getLongitude());
|
||||
}
|
||||
|
||||
public static LatLon getWeightCenter(Way way, Map<Long, LatLon> nodes){
|
||||
List<WayNode> wayNodes = way.getWayNodes();
|
||||
ArrayList<LatLon> arrayList = new ArrayList<LatLon>(wayNodes.size());
|
||||
for(WayNode n : wayNodes){
|
||||
if(nodes.containsKey(n.getNodeId())){
|
||||
arrayList.add(nodes.get(n.getNodeId()));
|
||||
}
|
||||
}
|
||||
return getWeightCenter(arrayList);
|
||||
}
|
||||
|
||||
public static LatLon getWeightCenterForNodes(Way way, Map<Long, Node> nodes){
|
||||
List<WayNode> wayNodes = way.getWayNodes();
|
||||
ArrayList<Node> arrayList = new ArrayList<Node>(wayNodes.size());
|
||||
for(WayNode n : wayNodes){
|
||||
if(nodes.containsKey(n.getNodeId())){
|
||||
arrayList.add(nodes.get(n.getNodeId()));
|
||||
}
|
||||
}
|
||||
return getWeightCenterForNodes(arrayList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets distance in meters
|
||||
*/
|
||||
public static double getDistance(LatLon l1, LatLon l2){
|
||||
return getDistance(l1, l2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Theses methods operate with degrees (evaluating tiles & vice versa)
|
||||
* degree longitude measurements (-180, 180) [27.56 Minsk]
|
||||
// degree latitude measurements (90, -90) [53.9]
|
||||
*/
|
||||
|
||||
// TODO check boundaries
|
||||
public static double getTileNumberX(int zoom, double longitude){
|
||||
int n = 1 << zoom;
|
||||
return (longitude + 180d)/360d * n;
|
||||
}
|
||||
|
||||
public static double getTileNumberY(int zoom, double latitude){
|
||||
int n = 1 << zoom;
|
||||
double eval = Math.log( Math.tan(Math.toRadians(latitude)) + 1/Math.cos(Math.toRadians(latitude)) );
|
||||
return (1 - eval / Math.PI) / 2 * n;
|
||||
}
|
||||
|
||||
public static double getLongitudeFromTile(int zoom, double x) {
|
||||
return x / (1 << zoom) * 360.0 - 180.0;
|
||||
}
|
||||
|
||||
|
||||
public static double getLatitudeFromTile(int zoom, double y){
|
||||
return Math.atan(Math.sinh(Math.PI * (1 - 2 * y / (1 << zoom)))) * 180d / Math.PI;
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String s){
|
||||
return s == null || s.length() == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static boolean objectEquals(Object a, Object b){
|
||||
if(a == null){
|
||||
return b == null;
|
||||
} else {
|
||||
return a.equals(b);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean tag(Entity e, String name, String value){
|
||||
String tag = getTag(e, name);
|
||||
return value.equals(tag);
|
||||
}
|
||||
}
|
78
DataExtractionOSM/src/com/anvisics/data/City.java
Normal file
78
DataExtractionOSM/src/com/anvisics/data/City.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
package com.anvisics.data;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Node;
|
||||
|
||||
import com.anvisics.NodeUtil;
|
||||
import com.anvisics.NodeUtil.LatLon;
|
||||
|
||||
public class City {
|
||||
|
||||
public enum CityType {
|
||||
CITY(10000), TOWN(5000), VILLAGE(1000), HAMLET(300), SUBURB(300);
|
||||
|
||||
private double radius;
|
||||
private CityType(double radius){
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
}
|
||||
|
||||
private final Node el;
|
||||
private CityType type = null;
|
||||
private Map<String, Street> streets = new TreeMap<String, Street>();
|
||||
|
||||
public City(Node el){
|
||||
this.el = el;
|
||||
String place = NodeUtil.getTag(el, "place");
|
||||
for(CityType t : CityType.values()){
|
||||
if(t.name().equalsIgnoreCase(place)){
|
||||
type = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Street registerBuilding(LatLon point, Entity e){
|
||||
String number = NodeUtil.getTag(e, "addr:housenumber");
|
||||
String street = NodeUtil.getTag(e, "addr:street");
|
||||
if( street != null && number != null){
|
||||
if(!streets.containsKey(street)){
|
||||
streets.put(street, new Street(street));
|
||||
}
|
||||
streets.get(street).registerBuilding(point, e);
|
||||
return streets.get(street);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String getName(){
|
||||
return NodeUtil.getTag(el, "name");
|
||||
}
|
||||
|
||||
public CityType getType(){
|
||||
return type;
|
||||
}
|
||||
|
||||
public Node getNode(){
|
||||
return el;
|
||||
}
|
||||
|
||||
public Collection<Street> getStreets(){
|
||||
return streets.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "City [" +type+"] " + getName();
|
||||
}
|
||||
|
||||
}
|
134
DataExtractionOSM/src/com/anvisics/data/DataTileManager.java
Normal file
134
DataExtractionOSM/src/com/anvisics/data/DataTileManager.java
Normal file
|
@ -0,0 +1,134 @@
|
|||
package com.anvisics.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.anvisics.NodeUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <T> - object to store in that manager
|
||||
*/
|
||||
public class DataTileManager<T> {
|
||||
|
||||
private int zoom = 15;
|
||||
|
||||
/**
|
||||
* map for objects stores as 'xTile_yTile' -> List<T>
|
||||
*/
|
||||
private Map<String, List<T>> objects = new HashMap<String, List<T>>();
|
||||
|
||||
public int getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
|
||||
public void setZoom(int zoom) {
|
||||
// TODO !!! it is required to reindex all stored objects
|
||||
if(!objects.isEmpty()){
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
this.zoom = zoom;
|
||||
}
|
||||
|
||||
private void putObjects(int tx, int ty, List<T> r){
|
||||
if(objects.containsKey(evTile(tx, ty))){
|
||||
r.addAll(objects.get(evTile(tx, ty)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @depth of the neighbor tile to visit
|
||||
* returns not exactly sorted list,
|
||||
* however the first objects are from closer tile than last
|
||||
*/
|
||||
public List<T> getClosestObjects(double latitude, double longitude, int depth){
|
||||
int tileX = (int) NodeUtil.getTileNumberX(zoom, longitude);
|
||||
int tileY = (int) NodeUtil.getTileNumberY(zoom, latitude);
|
||||
List<T> result = new ArrayList<T>();
|
||||
|
||||
|
||||
putObjects(tileX, tileY, result);
|
||||
|
||||
// that's very difficult way visiting node :
|
||||
// similar to visit like spiral
|
||||
// however the simplest way could visit by matrix & after that sort tiles by distance (that's less efficient)
|
||||
|
||||
// go through circle
|
||||
for (int i = 1; i <= depth; i++) {
|
||||
|
||||
// goes à
|
||||
for (int j = 0; j <= i; j++) {
|
||||
// left & right
|
||||
int dx = j == 0 ? 0 : -1;
|
||||
for (; dx < 1 || (j < i && dx == 1); dx += 2) {
|
||||
// north
|
||||
putObjects(tileX + dx * j, tileY + i, result);
|
||||
// east
|
||||
putObjects(tileX + i, tileY - dx * j, result);
|
||||
// south
|
||||
putObjects(tileX - dx * j, tileY - i, result);
|
||||
// west
|
||||
putObjects(tileX - i, tileY + dx * j, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String evTile(int tileX, int tileY){
|
||||
return tileX +"_"+tileY;
|
||||
}
|
||||
|
||||
|
||||
public String evaluateTile(double latitude, double longitude){
|
||||
int tileX = (int) NodeUtil.getTileNumberX(zoom, longitude);
|
||||
int tileY = (int) NodeUtil.getTileNumberY(zoom, latitude);
|
||||
return evTile(tileX, tileY);
|
||||
}
|
||||
|
||||
public String registerObject(double latitude, double longitude, T object){
|
||||
String tile = evaluateTile(latitude, longitude);
|
||||
if(!objects.containsKey(tile)){
|
||||
objects.put(tile, new ArrayList<T>());
|
||||
}
|
||||
objects.get(tile).add(object);
|
||||
return tile;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// testing way to search
|
||||
public static void print(int x, int y){
|
||||
System.out.println(x + (y-1)*5);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int tileX = 3;
|
||||
int tileY = 3;
|
||||
int depth = 3;
|
||||
for(int i=1; i<=depth; i++){
|
||||
|
||||
// goes à
|
||||
for(int j=0; j<=i; j++){
|
||||
// left & right
|
||||
int dx = j==0 ? 0 : -1;
|
||||
for(; dx < 1 || (j < i && dx == 1); dx +=2){
|
||||
// north
|
||||
print(tileX + dx * j, tileY + i);
|
||||
// east
|
||||
print(tileX + i, tileY - dx *j);
|
||||
// south
|
||||
print(tileX - dx * j, tileY - i);
|
||||
// west
|
||||
print(tileX - i, tileY + dx *j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
109
DataExtractionOSM/src/com/anvisics/data/Region.java
Normal file
109
DataExtractionOSM/src/com/anvisics/data/Region.java
Normal file
|
@ -0,0 +1,109 @@
|
|||
package com.anvisics.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Node;
|
||||
|
||||
import com.anvisics.NodeUtil;
|
||||
import com.anvisics.NodeUtil.LatLon;
|
||||
import com.anvisics.data.City.CityType;
|
||||
|
||||
public class Region {
|
||||
private Entity entity;
|
||||
|
||||
private DataTileManager<Node> amenities = new DataTileManager<Node>();
|
||||
|
||||
private Map<CityType, Collection<City>> cities = new HashMap<CityType, Collection<City>>();
|
||||
{
|
||||
for(CityType type : CityType.values()){
|
||||
cities.put(type, new ArrayList<City>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Region(Entity entity){
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
|
||||
public void setEntity(Entity e){
|
||||
this.entity = e;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return entity == null ? "" : NodeUtil.getTag(entity, "name");
|
||||
}
|
||||
|
||||
public Collection<City> getCitiesByType(CityType type){
|
||||
return cities.get(type);
|
||||
}
|
||||
|
||||
public Collection<City> getCitiesByName(String name){
|
||||
return getCityByName(name, true, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public Collection<City> getSuggestedCities(String name, int number){
|
||||
return getCityByName(name, false, number);
|
||||
}
|
||||
|
||||
protected Collection<City> getCityByName(String name, boolean exactMatch, int number){
|
||||
List<City> l = new ArrayList<City>();
|
||||
for(CityType type : CityType.values()){
|
||||
for(City c : cities.get(type)){
|
||||
if( (exactMatch && c.getName().equalsIgnoreCase(name)) ||
|
||||
(!exactMatch && c.getName().toLowerCase().startsWith(name.toLowerCase())
|
||||
)){
|
||||
l.add(c);
|
||||
if(l.size() >= number){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
public City getClosestCity(LatLon point){
|
||||
City closest = null;
|
||||
double relDist = Double.POSITIVE_INFINITY;
|
||||
for(CityType t : CityType.values()){
|
||||
for(City c : cities.get(t)){
|
||||
double rel = NodeUtil.getDistance(c.getNode(), point) / t.getRadius();
|
||||
if(rel < 1) {
|
||||
return c; // we are in that city
|
||||
}
|
||||
if(rel < relDist){
|
||||
closest = c;
|
||||
relDist = rel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
}
|
||||
|
||||
public List<Node> getClosestAmenities(double latitude, double longitude){
|
||||
return amenities.getClosestObjects(latitude, longitude, 2);
|
||||
}
|
||||
|
||||
public void registerAmenity(Node n){
|
||||
amenities.registerObject(n.getLatitude(), n.getLongitude(), n);
|
||||
}
|
||||
|
||||
public City registerCity(Node c){
|
||||
City city = new City(c);
|
||||
if(city.getType() != null && !NodeUtil.isEmpty(city.getName())){
|
||||
cities.get(city.getType()).add(city);
|
||||
return city;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
36
DataExtractionOSM/src/com/anvisics/data/Street.java
Normal file
36
DataExtractionOSM/src/com/anvisics/data/Street.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
package com.anvisics.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
|
||||
|
||||
import com.anvisics.NodeUtil.LatLon;
|
||||
|
||||
public class Street {
|
||||
|
||||
private final String name;
|
||||
private Map<Entity, LatLon> buildings = new HashMap<Entity, LatLon>();
|
||||
|
||||
public Street(String name){
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void registerBuilding(LatLon point, Entity e){
|
||||
buildings.put(e, point);
|
||||
}
|
||||
|
||||
public Set<Entity> getBuildings() {
|
||||
return buildings.keySet();
|
||||
}
|
||||
|
||||
public LatLon getLocationBuilding(Entity e){
|
||||
return buildings.get(e);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue