質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

1130閲覧

osmdroidでポリゴンの作成

takes.it.easy

総合スコア18

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2021/06/21 05:49

編集2021/06/23 06:24

前提・実現したいこと

1.
osmdroidで表示したマップ上をタッチしてマーカーを追加していき、そのマーカーで囲まれたエリアをポリゴンにしたい。
しかし古いポリゴンが保持されたまま描画してしまい、重なる部分が出てくる。(画像)
イメージ説明
2.
また、すでに囲まれたポリゴン内にマーカーを追加できない。
イメージ説明
ポリゴンやポリラインを使用しているのはユーザーに「このエリアを囲みました」というのをわかりやすくするためであり、最悪マーカのみでも構わない。ができればポリゴンを使用して囲まれたエリアの色を変更してわかりやすいようにしたい。。

該当のソースコード

Java

1import android.app.Activity; 2import android.content.Context; 3import android.content.Intent; 4import android.graphics.Color; 5import android.graphics.drawable.Drawable; 6import android.os.Bundle; 7import android.preference.PreferenceManager; 8import android.view.View; 9import android.widget.Button; 10import android.widget.TextView; 11import org.osmdroid.api.IMapController; 12import org.osmdroid.events.MapEventsReceiver; 13import org.osmdroid.tileprovider.MapTileProviderBasic; 14import org.osmdroid.tileprovider.tilesource.ITileSource; 15import org.osmdroid.tileprovider.tilesource.XYTileSource; 16import org.osmdroid.util.GeoPoint; 17import org.osmdroid.views.MapView; 18import org.osmdroid.views.overlay.MapEventsOverlay; 19import org.osmdroid.views.overlay.Marker; 20import org.osmdroid.views.overlay.Polygon; 21import org.osmdroid.views.overlay.TilesOverlay; 22import java.util.ArrayList; 23import java.util.List; 24 25public class DesignatedOnTheMapMainActivity extends Activity { 26 // private static double MAP_LAT, MAP_LON; 27 private static final double MAP_LAT = 緯度; 28 private static final double MAP_LON = 経度; 29 private static final double MAP_ZOOM = 15.0; 30 // boolean isFirstGetLoc = false; 31 private MapView mapView2 = null; 32 private TextView latlng = null; 33 private IMapController mapController = null; 34 Marker nowDot = null; 35 private static final String TILE_SEVER = "https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/"; 36 37 GeoPoint centerPoint = new GeoPoint(MAP_LAT, MAP_LON); 38 39  @Override 40   protected void onCreate(Bundle savedInstanceState) { 41   super.onCreate(savedInstanceState); 42 43   org.osmdroid.config.Configuration.getInstance().load(getApplicationContext(), 44 PreferenceManager.getDefaultSharedPreferences(getApplicationContext())); 45 46   setContentView(R.layout.designated_on_the_map_main_activity); 47 48   MapView mapView2 = findViewById(R.id.mapView2); 49   mapView2.setMultiTouchControls(true); 50 51   IMapController mapController = mapView2.getController(); 52   mapController.setZoom(MAP_ZOOM); 53 54   mapController.setCenter(centerPoint); 55 56   mapView2.setTilesScaledToDpi(true); 57 58   final MapTileProviderBasic tileProvider = new MapTileProviderBasic(getApplicationContext()); 59 60   ITileSource tileSource = new XYTileSource("GSI", 14, 24, 256, ".jpg", new String[]{TILE_SEVER}); 61 62   tileProvider.setTileSource(tileSource); 63   final TilesOverlay tilesOverlay = new TilesOverlay(tileProvider, this.getApplicationContext()); 64   tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT); 65   mapView2.getOverlays().add(tilesOverlay); 66       67      List<GeoPoint> geoPoints = new ArrayList<>(); 68 69   MapEventsReceiver events = new MapEventsReceiver() { 70   @Override 71   public boolean singleTapConfirmedHelper(GeoPoint p) { 72   TextView latlng = findViewById(R.id.latlng); 73   Marker marker = new Marker( mapView2 ); 74   geoPoints.add(new GeoPoint(p.getLatitude(), p.getLongitude())); 75 76   marker.setPosition(p); 77   mapView2.getOverlays().add(marker); 78 79 latlng.setText(p.toString()); 80 81   Polygon polygon = new Polygon(); 82   Polygon oldPolygon = new Polygon(); 83   mapView2.invalidate(); 84   polygon.setVisible(true); 85   polygon.setPoints(geoPoints); 86   mapView2.getOverlays().add(polygon); 87   if(oldPolygon != null){ 88   mapView2.getOverlays().remove(oldPolygon); 89   } 90   oldPolygon = polygon; 91 92 93   return true; 94   } 95 96   @Override 97   public boolean longPressHelper(GeoPoint p) { 98   return false; 99   } 100    }; 101 102 103 104   MapEventsOverlay OverlayEvents = new MapEventsOverlay(events); 105   mapView2.getOverlays().add(OverlayEvents); 106    } 107}

試したこと

1.
以下のサイトを参考にして古いポリゴンの削除を試みたがうまくいかず。
http://ja.uwenku.com/question/p-xfvtahqy-qc.html

2.
ポリゴンの代わりにポリラインを使用すればエリアではなくなるため、自由にマーカーを追加できる。しかしその場合、終点と始点を接続できない。(わかりやすさのために始点と終点は接続したい)

補足情報(FW/ツールのバージョンなど)

AndroidStudio4.2
osmdroid6.1.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ひとまず、タップしたポイントを1つのポリゴンにするように修正。

(長押しすると直近のマーカーも消えるようにしてみました)

Java

1(略) 2 List<GeoPoint> geoPoints = new ArrayList<>(); 3 List<Marker> markers = new ArrayList<>(); 4 final Polygon[] oldPolygon = {null}; 5 6 MapEventsReceiver events = new MapEventsReceiver() { 7 @Override 8 public boolean singleTapConfirmedHelper(GeoPoint p) { 9 TextView latlng = findViewById(R.id.latlng); 10 latlng.setText(p.toString()); 11 12 if(oldPolygon[0] != null){ 13 mapView2.getOverlays().remove(oldPolygon[0]); 14 } 15 geoPoints.add(p.clone()); 16 Marker marker = new Marker(mapView2); 17 marker.setPosition(p); 18 mapView2.getOverlays().add(marker); 19 markers.add(marker); 20 21 Polygon polygon = new Polygon(); 22 mapView2.invalidate(); 23 polygon.setPoints(geoPoints); 24 mapView2.getOverlays().add(polygon); 25 polygon.setVisible(true); 26 oldPolygon[0] = polygon; 27 return true; 28 } 29 30 @Override 31 public boolean longPressHelper(GeoPoint p) { 32 if(oldPolygon[0] != null){ 33 mapView2.getOverlays().remove(oldPolygon[0]); 34 } 35 markers.get(markers.size()-1).remove(mapView2); 36 markers.remove(markers.size()-1); 37 geoPoints.remove(geoPoints.size()-1); 38 Polygon polygon = new Polygon(); 39 mapView2.invalidate(); 40 polygon.setPoints(geoPoints); 41 mapView2.getOverlays().add(polygon); 42 polygon.setVisible(true); 43 oldPolygon[0] = polygon; 44 return true; 45 } 46 }; 47(略)

説明:

oldPolygonを保持しておき、ポイント追加時に消すという考え方はあっています。
しかし質問文記載のコードでは、

Polygon oldPolygon = new Polygon();

の時点で、oldPolygonが新しく生成されてしまい、追加前の情報が消えてしまっています。

ですので、内部クラスeventsの外でoldPolygonを定義し、タップ(マーカー追加)の都度、その情報を保持するようにしています。

(この時点でJava歴=Android Studio歴=5時間くらいなので、詳しい人から見たら書き方に突っ込みどころがあるかもしれません)


「すでに描画したポリゴンの内部をタップしたときに、新しい形でポリゴンを生成する」という動作を直接実現する関数がosmdroidには存在しないようです。
(実装上Polygon描画の時点で内部にある点は無視されてスキップされていると思われます)
考え方として、
・タップした地点が、それまでのポリゴンの内部にあるかどうかを判定。
・内部にある場合は、一番近い2点の間に、直近のタップ点を追加する(geoPointsのインデックスを並び替える)
というアルゴリズムになろうかと思います。

投稿2021/06/25 13:30

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takes.it.easy

2021/06/28 02:48

回答ありがとうございます。 なぜポリゴンが更新されないのかの理由が判明し有難い限りです。 osmdroidにはポリゴン内部をタップしたときに更新する機能がないとのことで、ポリラインで全体の形状を決め、最終決定と判断した場合にポリゴンとする。としたほうがスムーズそうですね。 長押しで直近の点を削除するコードに関しては参考にさせていただきます。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問