Skip to content

Commit b8bb5d1

Browse files
authored
Merge pull request #22 from scottlandis/master
Min viable OGC SOS capability
2 parents ecaa227 + e27be61 commit b8bb5d1

25 files changed

+1187
-273
lines changed

sample/TORGIListener/app/src/main/java/tech/plugs/torgilistener/AbstractSOSBroadcastTransceiver.java

+42-27
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
import android.content.Intent;
66
import android.util.Log;
77

8+
import org.json.JSONArray;
9+
import org.json.JSONException;
10+
import org.json.JSONObject;
11+
812
import java.io.StringWriter;
913
import java.text.ParseException;
1014
import java.text.SimpleDateFormat;
@@ -77,11 +81,27 @@ public void onMessageReceived(Context context,String source,String input) {
7781
}
7882

7983
public final static String getOperationDescribeSensor() {
80-
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><DescribeSensor version=\"1.0.0\" service=\"SOS\" mobileEnabled=\"true\" xmlns=\"http://www.opengis.net/sos/1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosDescribeSensor.xsd\" outputFormat=\"text/xml;subtype=&quot;sensorML/1.0.1&quot;\"><procedure>urn:ogc:object:feature:Sensor:IFGI:ifgi-sensor-1</procedure></DescribeSensor>";
84+
JSONObject obj = new JSONObject();
85+
try {
86+
obj.put("request","DescribeSensor");
87+
obj.put("service","SOS");
88+
obj.put("version","2.0.0");
89+
} catch (JSONException e) {
90+
e.printStackTrace();
91+
}
92+
return obj.toString();
8193
}
8294

8395
public final static String getOperationGetCapabilities() {
84-
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><GetCapabilities xmlns=\"http://www.opengis.net/sos/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0http://schemas.opengis.net/sos/1.0.0/sosGetCapabilities.xsd\" service=\"SOS\" updateSequence=\"\"><ows:AcceptVersions><ows:Version>1.0.0</ows:Version></ows:AcceptVersions><ows:Sections><ows:Section>OperationsMetadata</ows:Section><ows:Section>ServiceIdentification</ows:Section><ows:Section>Filter_Capabilities</ows:Section><ows:Section>Contents</ows:Section></ows:Sections></GetCapabilities>";
96+
JSONObject obj = new JSONObject();
97+
try {
98+
obj.put("request","GetCapabilities");
99+
obj.put("service","SOS");
100+
} catch (JSONException e) {
101+
e.printStackTrace();
102+
}
103+
104+
return obj.toString();
85105
}
86106

87107
public static long parseTime(String time) {
@@ -105,7 +125,7 @@ public static String formatTime(long time) {
105125
* @return
106126
*/
107127
public static String getOperationGetObservations() {
108-
return getOperationGetObservations(Long.MIN_VALUE, Long.MIN_VALUE);
128+
return getOperationGetObservations(Long.MIN_VALUE, Long.MAX_VALUE);
109129
}
110130

111131
/**
@@ -115,31 +135,26 @@ public static String getOperationGetObservations() {
115135
* @return
116136
*/
117137
public static String getOperationGetObservations(long start, long end) {
118-
StringWriter writer = new StringWriter();
119-
writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
120-
"<GetObservation xmlns=\"http://www.opengis.net/sos/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0\n" +
121-
"http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd\" service=\"SOS\" version=\"1.0.0\" srsName=\"urn:ogc:def:crs:EPSG:4326\">\n" +
122-
" <offering>TORGI</offering>\n"); //TODO change this type of offering
123-
if (end > Long.MIN_VALUE) {
124-
writer.append(" <eventTime>\n" +
125-
" <ogc:TM_During>\n" +
126-
" <ogc:PropertyName>urn:ogc:data:time:iso8601</ogc:PropertyName>\n" +
127-
" <gml:TimePeriod>\n" +
128-
" <gml:beginPosition>");
129-
writer.append(formatTime(start));
130-
writer.append("</gml:beginPosition>\n" +
131-
" <gml:endPosition>");
132-
writer.append(formatTime(end));
133-
writer.append("</gml:endPosition>\n" +
134-
" </gml:TimePeriod>\n" +
135-
" </ogc:TM_During>\n" +
136-
" </eventTime>\n");
138+
JSONObject obj = new JSONObject();
139+
try {
140+
obj.put("request","GetObservation");
141+
obj.put("service","SOS");
142+
obj.put("version","2.0.0");
143+
if ((start != Long.MIN_VALUE) && (end != Long.MAX_VALUE)) {
144+
JSONObject temporalFilter = new JSONObject();
145+
JSONObject during = new JSONObject();
146+
during.put("ref","om:phenomenonTime");
147+
JSONArray values = new JSONArray();
148+
values.put(formatTime(start));
149+
values.put(formatTime(end));
150+
during.put("value",values);
151+
temporalFilter.put("during",during);
152+
obj.put("temporalFilter",temporalFilter);
153+
}
154+
} catch (JSONException e) {
155+
e.printStackTrace();
137156
}
138-
//TODO need to implement " <procedure>urn:ogc:object:feature:Sensor:IFGI:ifgi-sensor-1</procedure>\n" +
139-
//TODO need to implement " <observedProperty>urn:ogc:def:phenomenon:OGC:1.0.30:waterlevel</observedProperty>\n" +
140-
writer.append(" <responseFormat>text/xml;subtype=&quot;om/1.0.0&quot;</responseFormat>\n" +
141-
"</GetObservation>");
142157

143-
return writer.toString();
158+
return obj.toString();
144159
}
145160
}

sample/TORGIListener/app/src/main/java/tech/plugs/torgilistener/MainActivity.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,20 @@ protected void onCreate(Bundle savedInstanceState) {
2929
bDescribeSensor = findViewById(R.id.sendDescribeSensor);
3030
bGetCapabilities = findViewById(R.id.sendGetCapabilities);
3131
bGetObservations = findViewById(R.id.sendGetObservations);
32-
bDescribeSensor.setOnClickListener(view -> AbstractSOSBroadcastTransceiver.broadcast(MainActivity.this,AbstractSOSBroadcastTransceiver.getOperationDescribeSensor()));
33-
bGetCapabilities.setOnClickListener(view -> AbstractSOSBroadcastTransceiver.broadcast(MainActivity.this,AbstractSOSBroadcastTransceiver.getOperationGetCapabilities()));
34-
bGetObservations.setOnClickListener(view -> AbstractSOSBroadcastTransceiver.broadcast(MainActivity.this,AbstractSOSBroadcastTransceiver.getOperationGetObservations()));
32+
bDescribeSensor.setOnClickListener(view -> broadcast(AbstractSOSBroadcastTransceiver.getOperationDescribeSensor()));
33+
bGetCapabilities.setOnClickListener(view -> broadcast(AbstractSOSBroadcastTransceiver.getOperationGetCapabilities()));
34+
bGetObservations.setOnClickListener(view -> broadcast(AbstractSOSBroadcastTransceiver.getOperationGetObservations()));
3535
transceiver = new SampleTransceiver();
3636
IntentFilter intentFilter = new IntentFilter(AbstractSOSBroadcastTransceiver.ACTION_SOS);
3737
registerReceiver(transceiver, intentFilter);
3838

3939
}
4040

41+
private void broadcast(String value) {
42+
response.setText(getString(R.string.waiting_for_message));
43+
AbstractSOSBroadcastTransceiver.broadcast(MainActivity.this,value);
44+
}
45+
4146
@Override
4247
public void onResume() {
4348
super.onResume();

sample/TORGIListener/app/src/main/res/layout/activity_main.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
android:id="@+id/messgage"
2828
android:layout_width="match_parent"
2929
android:layout_height="wrap_content"
30-
android:text="Waiting for message"
30+
android:text="@string/waiting_for_message"
3131
android:layout_margin="4dp"
3232
android:background="@android:color/white"/>
3333

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
<resources>
22
<string name="app_name">TORGI Listener</string>
3+
<string name="waiting_for_message">Waiting for message…</string>
34
</resources>

torgi/build.gradle

+9-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ apply plugin: 'com.android.application'
22

33
android {
44
compileSdkVersion 27
5+
6+
packagingOptions {
7+
exclude 'META-INF/DEPENDENCIES.txt'
8+
exclude 'META-INF/DEPENDENCIES'
9+
}
10+
511
defaultConfig {
612
applicationId "org.sofwerx.torgi"
713
minSdkVersion 24
@@ -53,11 +59,12 @@ dependencies {
5359
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
5460
viewerImplementation 'com.github.PhilJay:MPAndroidChart:v3.0.3' //for charts
5561
viewerImplementation 'org.osmdroid:osmdroid-android:6.0.2'
56-
implementation 'org.apache.commons:commons-math3:3.0' //for statistical analysis
62+
implementation 'org.apache.httpcomponents:httpclient:4.5.6' //for SOS server
63+
implementation 'org.nanohttpd:nanohttpd:2.3.1' //for SOS server
64+
implementation 'org.apache.commons:commons-math3:3.6.1' //for statistical analysis
5765
implementation 'mil.nga.geopackage:geopackage-android:3.0.2'
5866
implementation 'com.android.support:appcompat-v7:27.1.1'
5967
viewerImplementation 'com.android.support.constraint:constraint-layout:1.1.3'
60-
//implementation 'com.google.android.gms:play-services-maps:15.0.1'
6168
implementation 'com.android.support:design:27.1.1'
6269
testImplementation 'junit:junit:4.12'
6370
androidTestImplementation 'com.android.support.test:runner:1.0.2'

torgi/src/main/java/org/sofwerx/torgi/Config.java

+19
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@
66
import android.preference.PreferenceManager;
77

88
import java.io.File;
9+
import java.util.UUID;
910

1011
public class Config {
1112
public final static String PREFS_SAVE_DIR = "savedir";
13+
public final static String PREFS_AUTO_SHARE = "autoshare";
1214
public final static String PREFS_PROCESS_EW = "processew";
15+
public final static String PREFS_UUID = "callsign";
1316

1417
private static Config instance = null;
1518
private String savedDir = null;
1619
private boolean processEWonboard = false;
1720
private SharedPreferences prefs = null;
21+
private String uuid = null;
1822
private Context context;
1923

2024
private Config(Context context) {
@@ -36,10 +40,25 @@ public void setProcessEWonboard(boolean processEWonboard) {
3640
edit.commit();
3741
}
3842

43+
public boolean isAutoShareEnabled() {
44+
return prefs.getBoolean(PREFS_AUTO_SHARE,true);
45+
}
46+
3947
public boolean processEWOnboard() {
4048
return processEWonboard;
4149
}
4250

51+
public String getUuid() {
52+
if (uuid == null) {
53+
uuid = prefs.getString(PREFS_UUID,null);
54+
if (uuid == null) {
55+
uuid = UUID.randomUUID().toString();
56+
prefs.edit().putString(PREFS_UUID,uuid).apply();
57+
}
58+
}
59+
return uuid;
60+
}
61+
4362
public String getSavedDir() {
4463
if (savedDir == null) {
4564
/*savedDir = prefs.getString(PREFS_SAVE_DIR, null);

torgi/src/main/java/org/sofwerx/torgi/ogc/AbstractSOSBroadcastTransceiver.java

+11-57
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import android.util.Log;
77

88
import org.sofwerx.torgi.BuildConfig;
9+
import org.sofwerx.torgi.ogc.sos.DescribeSensor;
10+
import org.sofwerx.torgi.ogc.sos.GetCapabilities;
11+
import org.sofwerx.torgi.ogc.sos.GetObservations;
912

1013
import java.io.StringWriter;
1114
import java.text.ParseException;
@@ -28,7 +31,6 @@
2831
*
2932
*/
3033
public abstract class AbstractSOSBroadcastTransceiver extends BroadcastReceiver {
31-
private final static SimpleDateFormat dateFormatISO8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
3234
protected final static String TAG = "OGC.SOS";
3335
public static final String ACTION_SOS = "org.sofwerx.torgi.ogc.ACTION_SOS";
3436
private static final String EXTRA_PAYLOAD = "SOS";
@@ -81,69 +83,21 @@ public void onMessageReceived(Context context,String source,String input) {
8183
}
8284

8385
public final static String getOperationDescribeSensor() {
84-
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><DescribeSensor version=\"1.0.0\" service=\"SOS\" mobileEnabled=\"true\" xmlns=\"http://www.opengis.net/sos/1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosDescribeSensor.xsd\" outputFormat=\"text/xml;subtype=&quot;sensorML/1.0.1&quot;\"><procedure>urn:ogc:object:feature:Sensor:IFGI:ifgi-sensor-1</procedure></DescribeSensor>";
86+
return new DescribeSensor().toJSON().toString();
8587
}
8688

8789
public final static String getOperationGetCapabilities() {
88-
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?><GetCapabilities xmlns=\"http://www.opengis.net/sos/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0http://schemas.opengis.net/sos/1.0.0/sosGetCapabilities.xsd\" service=\"SOS\" updateSequence=\"\"><ows:AcceptVersions><ows:Version>1.0.0</ows:Version></ows:AcceptVersions><ows:Sections><ows:Section>OperationsMetadata</ows:Section><ows:Section>ServiceIdentification</ows:Section><ows:Section>Filter_Capabilities</ows:Section><ows:Section>Contents</ows:Section></ows:Sections></GetCapabilities>";
90+
return new GetCapabilities().toJSON().toString();
8991
}
9092

91-
public static long parseTime(String time) {
92-
if (time != null) {
93-
try {
94-
Date date = dateFormatISO8601.parse(time);
95-
return date.getTime();
96-
} catch (ParseException e) {
97-
e.printStackTrace();
98-
}
99-
}
100-
return Long.MIN_VALUE;
101-
}
102-
103-
public static String formatTime(long time) {
104-
return dateFormatISO8601.format(time);
105-
}
106-
107-
/**
108-
* Gets the recent observations
109-
* @return
110-
*/
11193
public static String getOperationGetObservations() {
112-
return getOperationGetObservations(Long.MIN_VALUE, Long.MIN_VALUE);
94+
return new GetObservations().toJSON().toString();
11395
}
11496

115-
/**
116-
* Gets a range of observations
117-
* @param start start time
118-
* @param end end time
119-
* @return
120-
*/
121-
public static String getOperationGetObservations(long start, long end) {
122-
StringWriter writer = new StringWriter();
123-
writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
124-
"<GetObservation xmlns=\"http://www.opengis.net/sos/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0\n" +
125-
"http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd\" service=\"SOS\" version=\"1.0.0\" srsName=\"urn:ogc:def:crs:EPSG:4326\">\n" +
126-
" <offering>TORGI</offering>\n"); //TODO change this type of offering
127-
if (end > Long.MIN_VALUE) {
128-
writer.append(" <eventTime>\n" +
129-
" <ogc:TM_During>\n" +
130-
" <ogc:PropertyName>urn:ogc:data:time:iso8601</ogc:PropertyName>\n" +
131-
" <gml:TimePeriod>\n" +
132-
" <gml:beginPosition>");
133-
writer.append(formatTime(start));
134-
writer.append("</gml:beginPosition>\n" +
135-
" <gml:endPosition>");
136-
writer.append(formatTime(end));
137-
writer.append("</gml:endPosition>\n" +
138-
" </gml:TimePeriod>\n" +
139-
" </ogc:TM_During>\n" +
140-
" </eventTime>\n");
141-
}
142-
//TODO need to implement " <procedure>urn:ogc:object:feature:Sensor:IFGI:ifgi-sensor-1</procedure>\n" +
143-
//TODO need to implement " <observedProperty>urn:ogc:def:phenomenon:OGC:1.0.30:waterlevel</observedProperty>\n" +
144-
writer.append(" <responseFormat>text/xml;subtype=&quot;om/1.0.0&quot;</responseFormat>\n" +
145-
"</GetObservation>");
146-
147-
return writer.toString();
97+
public static String getOperationGetObservations(long start, long stop) {
98+
GetObservations getObservations = new GetObservations();
99+
getObservations.setStartTime(start);
100+
getObservations.setStopTime(stop);
101+
return getObservations.toJSON().toString();
148102
}
149103
}

0 commit comments

Comments
 (0)