Skip to content
This repository was archived by the owner on Apr 23, 2026. It is now read-only.

Commit 2969bd2

Browse files
authored
Merge pull request #67 from ngageoint/createFeatureLayer
Create feature layer improvements
2 parents 96acbe8 + b6540dd commit 2969bd2

3 files changed

Lines changed: 157 additions & 92 deletions

File tree

mapcache/src/main/java/mil/nga/mapcache/GeoPackageMapFragment.java

Lines changed: 4 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
import java.util.Map;
113113
import java.util.concurrent.locks.Lock;
114114
import java.util.concurrent.locks.ReentrantLock;
115+
import java.util.regex.Pattern;
115116

116117
import mil.nga.geopackage.BoundingBox;
117118
import mil.nga.geopackage.GeoPackage;
@@ -181,6 +182,7 @@
181182
import mil.nga.mapcache.view.map.BasemapApplier;
182183
import mil.nga.mapcache.view.map.feature.FeatureViewActivity;
183184
import mil.nga.mapcache.viewmodel.GeoPackageViewModel;
185+
import mil.nga.mapcache.wizards.createfeature.NewFeatureLayerUI;
184186
import mil.nga.mapcache.wizards.createtile.IBoundingBoxManager;
185187
import mil.nga.mapcache.wizards.createtile.IMapView;
186188
import mil.nga.mapcache.wizards.createtile.NewTileLayerUI;
@@ -1819,97 +1821,7 @@ public void newLayerWizard() {
18191821
* Create feature layer menu
18201822
*/
18211823
private void createFeatureOption() {
1822-
if (getActivity() != null) {
1823-
LayoutInflater inflater = LayoutInflater.from(getActivity());
1824-
View createFeaturesView = inflater.inflate(R.layout.create_features,
1825-
null);
1826-
AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity(), R.style.AppCompatAlertDialogStyle);
1827-
dialog.setView(createFeaturesView);
1828-
1829-
final TextInputEditText nameInput = createFeaturesView
1830-
.findViewById(R.id.create_features_name_input);
1831-
final TextInputEditText minLatInput = createFeaturesView
1832-
.findViewById(R.id.bounding_box_min_latitude_input);
1833-
final TextInputEditText maxLatInput = createFeaturesView
1834-
.findViewById(R.id.bounding_box_max_latitude_input);
1835-
final TextInputEditText minLonInput = createFeaturesView
1836-
.findViewById(R.id.bounding_box_min_longitude_input);
1837-
final TextInputEditText maxLonInput = createFeaturesView
1838-
.findViewById(R.id.bounding_box_max_longitude_input);
1839-
final TextView preloadedLocationsButton = createFeaturesView
1840-
.findViewById(R.id.bounding_box_preloaded);
1841-
final Spinner geometryTypeSpinner = createFeaturesView
1842-
.findViewById(R.id.create_features_geometry_type);
1843-
1844-
GeoPackageUtils
1845-
.prepareBoundingBoxInputs(getActivity(), minLatInput,
1846-
maxLatInput, minLonInput, maxLonInput,
1847-
preloadedLocationsButton);
1848-
1849-
dialog.setPositiveButton(
1850-
getString(R.string.geopackage_create_features_label),
1851-
(DialogInterface d, int id) -> {
1852-
1853-
try {
1854-
1855-
String tableName = nameInput.getText().toString();
1856-
if (tableName.isEmpty()) {
1857-
throw new GeoPackageException(
1858-
getString(R.string.create_features_name_label)
1859-
+ " is required");
1860-
}
1861-
double minLat = Double.parseDouble(minLatInput
1862-
.getText().toString());
1863-
double maxLat = Double.parseDouble(maxLatInput
1864-
.getText().toString());
1865-
double minLon = Double.parseDouble(minLonInput
1866-
.getText().toString());
1867-
double maxLon = Double.parseDouble(maxLonInput
1868-
.getText().toString());
1869-
1870-
if (minLat > maxLat) {
1871-
throw new GeoPackageException(
1872-
getString(R.string.bounding_box_min_latitude_label)
1873-
+ " can not be larger than "
1874-
+ getString(R.string.bounding_box_max_latitude_label));
1875-
}
1876-
1877-
if (minLon > maxLon) {
1878-
throw new GeoPackageException(
1879-
getString(R.string.bounding_box_min_longitude_label)
1880-
+ " can not be larger than "
1881-
+ getString(R.string.bounding_box_max_longitude_label));
1882-
}
1883-
1884-
BoundingBox boundingBox = new BoundingBox(minLon,
1885-
minLat, maxLon, maxLat);
1886-
1887-
GeometryType geometryType = GeometryType
1888-
.fromName(geometryTypeSpinner
1889-
.getSelectedItem().toString());
1890-
String geoName = detailPageAdapter.getGeoPackageName();
1891-
if (geoName != null) {
1892-
if (!geoPackageViewModel.createFeatureTable(geoName, boundingBox, geometryType, tableName)) {
1893-
GeoPackageUtils
1894-
.showMessage(
1895-
getActivity(),
1896-
getString(R.string.geopackage_create_features_label),
1897-
"There was a problem generating a tile table");
1898-
}
1899-
}
1900-
1901-
1902-
} catch (Exception e) {
1903-
GeoPackageUtils
1904-
.showMessage(
1905-
getActivity(),
1906-
getString(R.string.geopackage_create_features_label),
1907-
e.getMessage());
1908-
}
1909-
}).setNegativeButton(getString(R.string.button_cancel_label),
1910-
(DialogInterface d, int id) -> d.cancel());
1911-
dialog.show();
1912-
}
1824+
NewFeatureLayerUI.newFeatureLayerPopup(getActivity(), geoPackageViewModel, detailPageAdapter.getGeoPackageName());
19131825
}
19141826

19151827

@@ -1930,6 +1842,7 @@ public void showMapIcons() {
19301842
ViewAnimation.rotateFadeIn(settingsIcon, 200);
19311843
layerFab.show();
19321844
}
1845+
19331846

19341847
/**
19351848
* Launches a wizard to create a new tile layer in the given geopackage

mapcache/src/main/java/mil/nga/mapcache/view/detail/DetailActionUtil.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,6 @@ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
406406
givenName);
407407
if (!allowed) {
408408
name.setError(context.getResources().getString(R.string.must_be_alphanumeric));
409-
addButton.setBackgroundColor(context.getResources().getColor(R.color.inactive_grey));
410409
addButton.setEnabled(false);
411410
}
412411
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package mil.nga.mapcache.wizards.createfeature;
2+
3+
import android.app.Activity;
4+
import android.content.DialogInterface;
5+
import android.text.Editable;
6+
import android.text.TextWatcher;
7+
import android.view.LayoutInflater;
8+
import android.view.View;
9+
import android.widget.Spinner;
10+
import android.widget.TextView;
11+
12+
import androidx.appcompat.app.AlertDialog;
13+
14+
import com.google.android.material.textfield.TextInputEditText;
15+
16+
import java.util.regex.Pattern;
17+
18+
import mil.nga.geopackage.BoundingBox;
19+
import mil.nga.geopackage.GeoPackageException;
20+
import mil.nga.mapcache.GeoPackageUtils;
21+
import mil.nga.mapcache.R;
22+
import mil.nga.mapcache.viewmodel.GeoPackageViewModel;
23+
import mil.nga.sf.GeometryType;
24+
25+
/**
26+
* Handlers for creating a new feature layer in a GeoPackage
27+
*/
28+
public class NewFeatureLayerUI {
29+
30+
/**
31+
* Create a dialog which accepts name, bounds, and type. Then create a feature layer
32+
* on submit
33+
* @param activity - calling activity to access UI
34+
* @param viewModel - viewModel to access GeoPackages in the repository
35+
* @param geoName - name of the GeoPackage to create the layer in
36+
*/
37+
public static void newFeatureLayerPopup(Activity activity, GeoPackageViewModel viewModel,
38+
String geoName){
39+
if (activity != null && viewModel != null && !geoName.isEmpty() && geoName != null) {
40+
LayoutInflater inflater = LayoutInflater.from(activity);
41+
View createFeaturesView = inflater.inflate(R.layout.create_features,
42+
null);
43+
AlertDialog.Builder dialog = new AlertDialog.Builder(activity, R.style.AppCompatAlertDialogStyle);
44+
dialog.setView(createFeaturesView);
45+
46+
final TextInputEditText nameInput = createFeaturesView
47+
.findViewById(R.id.create_features_name_input);
48+
final TextInputEditText minLatInput = createFeaturesView
49+
.findViewById(R.id.bounding_box_min_latitude_input);
50+
final TextInputEditText maxLatInput = createFeaturesView
51+
.findViewById(R.id.bounding_box_max_latitude_input);
52+
final TextInputEditText minLonInput = createFeaturesView
53+
.findViewById(R.id.bounding_box_min_longitude_input);
54+
final TextInputEditText maxLonInput = createFeaturesView
55+
.findViewById(R.id.bounding_box_max_longitude_input);
56+
final TextView preloadedLocationsButton = createFeaturesView
57+
.findViewById(R.id.bounding_box_preloaded);
58+
final Spinner geometryTypeSpinner = createFeaturesView
59+
.findViewById(R.id.create_features_geometry_type);
60+
61+
GeoPackageUtils.prepareBoundingBoxInputs(activity, minLatInput,
62+
maxLatInput, minLonInput, maxLonInput,
63+
preloadedLocationsButton);
64+
65+
dialog.setPositiveButton(
66+
activity.getString(R.string.geopackage_create_features_label),
67+
(DialogInterface d, int id) -> {
68+
69+
try {
70+
String tableName = nameInput.getText().toString();
71+
if (tableName.isEmpty()) {
72+
throw new GeoPackageException(
73+
activity.getString(R.string.create_features_name_label)
74+
+ " is required");
75+
}
76+
double minLat = Double.parseDouble(minLatInput.getText().toString());
77+
double maxLat = Double.parseDouble(maxLatInput.getText().toString());
78+
double minLon = Double.parseDouble(minLonInput.getText().toString());
79+
double maxLon = Double.parseDouble(maxLonInput.getText().toString());
80+
81+
if (minLat > maxLat) {
82+
throw new GeoPackageException(
83+
activity.getString(R.string.bounding_box_min_latitude_label)
84+
+ " can not be larger than "
85+
+ activity.getString(R.string.bounding_box_max_latitude_label));
86+
}
87+
88+
if (minLon > maxLon) {
89+
throw new GeoPackageException(
90+
activity.getString(R.string.bounding_box_min_longitude_label)
91+
+ " can not be larger than "
92+
+ activity.getString(R.string.bounding_box_max_longitude_label));
93+
}
94+
95+
BoundingBox boundingBox = new BoundingBox(minLon, minLat, maxLon, maxLat);
96+
97+
GeometryType geometryType = GeometryType.fromName(geometryTypeSpinner
98+
.getSelectedItem().toString());
99+
if (!viewModel.createFeatureTable(geoName, boundingBox, geometryType, tableName)) {
100+
GeoPackageUtils.showMessage(activity,
101+
activity.getString(R.string.geopackage_create_features_label),
102+
"There was a problem generating a tile table");
103+
}
104+
} catch (Exception e) {
105+
GeoPackageUtils.showMessage(activity,
106+
activity.getString(R.string.geopackage_create_features_label),
107+
e.getMessage());
108+
}
109+
}).setNegativeButton(activity.getString(R.string.button_cancel_label),
110+
(DialogInterface d, int id) -> d.cancel());
111+
AlertDialog createdDialog = dialog.create();
112+
createdDialog.setOnShowListener(dialog1 -> {
113+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
114+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(
115+
activity.getResources().getColor(R.color.textNavNotSelected,
116+
activity.getTheme()));
117+
});
118+
nameInput.setError("Name cannot be empty");
119+
nameInput.addTextChangedListener(new TextWatcher() {
120+
@Override
121+
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
122+
@Override
123+
public void onTextChanged(CharSequence s, int start, int before, int count) {}
124+
@Override
125+
public void afterTextChanged(Editable s) {
126+
String givenName = nameInput.getText() != null ? nameInput.getText().toString() : "";
127+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
128+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(
129+
activity.getResources().getColor(R.color.primaryButtonColor,
130+
activity.getTheme()));
131+
if(givenName.isEmpty()) {
132+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
133+
nameInput.setError("Name cannot be empty");
134+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(
135+
activity.getResources().getColor(R.color.textNavNotSelected,
136+
activity.getTheme()));
137+
} else {
138+
String pattern = activity.getResources().getString(R.string.regex_alphanumeric);
139+
boolean allowed = Pattern.matches(pattern, givenName);
140+
if (!allowed) {
141+
nameInput.setError(activity.getResources().getString(R.string.must_be_alphanumeric));
142+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
143+
createdDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(
144+
activity.getResources().getColor(R.color.textNavNotSelected,
145+
activity.getTheme()));
146+
}
147+
}
148+
}
149+
});
150+
createdDialog.show();
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)