トピックで説明されているタスクに遭遇したことがある場合、おそらくgetClosestPoint()メソッドの説明への参照以外の投稿があることに驚くでしょう。そのため、私のソリューションは確かにそれに基づいているとすぐに言います。 ただし、共有するのはそれほど多くのアルゴリズムの美しさではなく(APIを作成したYandexチームによって実現されました)、むしろ私に用意されたタスクに対する既成のソリューションとしてです。
当社はまた、IPテレフォニーおよびインターネットサービスの提供、および当社独自の光ファイバーのキロメートル単位の提供にも関与しています。 私たちにとって、目的のクライアントのオフィスがケーブルからどれだけ離れているかという問題は非常に重要です。
光学ルートを含むマップの作成から、カットの下でフォームに組み込まれた最短距離決定の実装まで、既製のソリューションを探します。
すべての作業は基本的に既製のソリューションとサンプルをコンパイルすることで構成されていることを、私はあなたを欺いたり、自分を隠そうとはしません。
タスクは次のとおりです。ユーザーが住所を入力します
- サイトおよびGETリクエストを使用するアドレスは、マップのあるページに転送されます
- マップ自体の特別な形式で
または、彼は自分で家を選んで、マウスを正しい場所に突っ込む。
その後、選択した住所と最も近い光ケーブルまでの距離を示すマークが地図に表示されます。 表示を簡単にするために、ケーブルに垂線を描画します(議論の余地のある解決策ですが、視覚的には結果が気に入りました)。
http://www.infotis.ru/maps.htmlに根拠がないように例を挙げます 。
作業はいくつかの段階に削減されました
- ケーブルを物理カードからYandex.Mapに転送します
- 曲線(ポリライン)の形でカードにケーブルを引きます
- カスタムコントロールを作成する
- 距離を計算する関数を書く
- 必要な住所と必要な座標を取得します
ステージ1
この段階では、ITの専門家と直接関係のない同僚の手によって、数十キロメートルのケーブルを地図上に配置する必要がありました。 ここでは、 ymikエディターが手伝ってくれました。 この投稿の発見から、最終的な選択は(Googleマップではなく)Yandex.Mapsを支持して行われました。
同僚の仕事をしばらくしてから、次の形式のテキストファイルを受け取りました(場所を散らかさないように、2ポイントの1つの曲線の例)
{ "name": "1", "center": { "lng": 37.62110402807594, "lat": 55.74879798509053, "zoom": 12 }, "styles": [{ "name": "ymikEditor#1315408925757#0", "style": { "lineStyle": { "strokeColor": "0000ff80", "strokeWidth": "5" } } }], "objects": [{ "style": "ymikEditor#1315408925757#0", "name": "1", "description": "1", "type": "Polyline", "points": [{ "lng": 37.62110402807594, "lat": 55.773576281653035 }, { "lng": 37.6235072873533, "lat": 55.74957254620929 }] }] }
ステージ2
ymikの作品のイメージと肖像で、これらの芸術を地図に描きます。
オブジェクトが変数val、mapにあることに同意します-
次は少しのコードです(シンプルですが、ソリューション自体はシンプルなので、コメントを付けましょう)
マップとシンプルなコントロールを作成します。 コードからわかるように、jQueryはプロセスにロードされます。これは、将来(YMaps.jQueryを使用した$の代わりに)使用します。
map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]); map.setCenter(new YMaps.GeoPoint(37.643347, 55.745478), 13); map.addControl(new YMaps.Zoom()); map.addControl(new YMaps.ToolBar()); map.addControl(new YMaps.ScaleLine()); map.addControl(new YMaps.TypeControl()); map.setType(YMaps.MapType.SATELLITE); // var moscowBounds = new YMaps.GeoBounds( new YMaps.GeoPoint(37.389705, 55.577759), new YMaps.GeoPoint(37.844264, 55.91086) );
線描画機能
polylines=[]; function draw_lines() { k = 0; // for (var j = 0; j < val['objects'].length; j++) // { if (val['objects'][j]['type'] == 'Polyline') // Points { Points = []; for (var i = 0; i < val['objects'][j]['points'].length; i++) { Points.push(new YMaps.GeoPoint(val['objects'][j]['points'][i]['lng'], val['objects'][j]['points'][i]['lat'])); } // pl = new YMaps.Polyline(Points, { style: { lineStyle: { strokeColor: val['styles'][k]['style']['lineStyle']['strokeColor'], strokeWidth: val['styles'][k]['style']['lineStyle']['strokeWidth'] } }, hasHint: 1 }); pl.name = val['objects'][j]['name']; pl.description = val['objects'][j]['description']; polylines.push(pl); // polylines map.addOverlay(pl); // k++; } if (val['objects'][j]['type'] == 'Placemark') // { var placemark = new YMaps.Placemark(new YMaps.GeoPoint(val['objects'][j]['points']['lng'], val['objects'][j]['points']['lat']), { style: val['objects'][j]['style'] }); placemark.name = val['objects'][j]['name']; placemark.description = val['objects'][j]['description']; map.addOverlay(placemark); } } }
ステージ3
この段階で、主な作業を行います。
まず第一に、ユーザーが必要な住所を入力して、ケーブルが労働者が通過する距離を確認できるフォームをマップ上に作成しておくといいでしょう。
次に、Yandexのネイティブコントロールの例を示します。http : //api.yandex.ru/maps/jsapi/examples/mapcontrolscustomizing.html
このモデルに従って、行動します。
このコントロールのデザイナーを連れてきます
function nearest_search(object_address) { // this.onAddToMap = function (map, position) { this.container = YMaps.jQuery("<div class='YMaps-button'> <i class='YMaps-button-c YMaps-button-l'><i></i></i><i class='YMaps-button-m YMaps-cursor-pointer'><i></i> <form id='find_nearest_form' action='#' class='YMaps-button-caption'> <input type='text' name='object_address' value='"+object_address+"' id='search_nearest_input' style='border:1px solid green;' size='22'/></form></i><i class='YMaps-button-c YMaps-button-r'><i></i></i></div>"); // ( ) this.map = map; this.position = position || new YMaps.ControlPosition(YMaps.ControlPosition.TOP_LEFT, new YMaps.Size(0, 40)); // , . // CSS-, this.container.css({ position: "absolute", zIndex: YMaps.ZIndex.CONTROL, width: "280px", }); this.position.apply(this.container); this.container.appendTo(this.map.getContainer()); } // this.onRemoveFromMap = function () { // , . }; }
フォームを送信する代わりに、距離を検索および計算する機能を開始するトリガー。
YMaps.jQuery('#find_nearest_form').submit(function () { showAddress(YMaps.jQuery("#search_nearest_input").val()); return false; });
次に、元のmaps.yandex.ruから「情報」要素のバリアントを作成します
完全に行う方法については、 http://api.yandex.ru/maps/articles/tasks/service.xml#how-to-use-create-information-toolで説明しています。
この場所ではジオコーディングは必要ないので、少し削減します
function InformationControl() { var geoResult, clickPlace, listener, map; // this.onAddToMap = function (parentMap) { map = parentMap; map.addCursor(YMaps.Cursor.HELP); // listener = YMaps.Events.observe(map, map.Events.Click, function (map, mEvent) { // var clickPoint = mEvent.getGeoPoint(); // ( ) if (geoResult) { map.removeOverlay(geoResult); result = null; } // - if (clickPlace) { map.removeOverlay(clickPlace); clickPlace = null; } // clickPlace = new YMaps.Placemark(clickPoint); clickPlace.description = clickPoint.toString(); map.addOverlay(clickPlace); // ( ) geotrack(clickPoint, clickPlace); }, this); } // this.onRemoveFromMap = function () { map.removeCursor(YMaps.Cursor.HELP); // , if (geoResult) {map.removeOverlay(geoResult); } // if (punchline) {map.removeOverlay(punchline); } if (clickPlace) {map.removeOverlay(clickPlace); } // listener.cleanup(); map = geoResult = clickPlace = listener = null; } }
ステージ4
ほら、すべてのボタンがあります-距離を決定するためのメイン関数を書き始めましょう。
function geotrack(clickPoint, clickPlace) { // - if (punchline) { map.removeOverlay(punchline); } nearest = 100000000000; // . . nearest_point = new YMaps.GeoPoint(0, 0); // for (var i = 0; i < polylines.length; i++) // - , { if (nearest > polylines[i].getClosestPoint(clickPoint)['point'].distance(clickPoint)) { nearest = polylines[i].getClosestPoint(clickPoint)['point'].distance(clickPoint); nearest_point = polylines[i].getClosestPoint(clickPoint)['point']; } } clickPlace.name = " : " + YMaps.humanDistance(nearest); clickPlace.description = ""; punchline = new YMaps.Polyline([clickPoint, nearest_point], { style: { lineStyle: { strokeColor: "ffffffff", strokeWidth: 2 } }, hashint: 1 }); punchline.name = " : " + YMaps.humanDistance(nearest); map.addOverlay(punchline); return clickPlace.name; }
ステージ5
住所で座標を検索しましょう。
再びYandexの例http://api.yandex.ru/maps/jsapi/examples/geocoding.html
function showAddress(value) { // map.removeOverlay(geoResult); // . strictBounds : true - (moscowBounds) var geocoder = new YMaps.Geocoder(value, { results: 1, boundedBy: moscowBounds, strictBounds : true }); // YMaps.Events.observe(geocoder, geocoder.Events.Load, function () { // , // if (this.length()) { geoResult = this.get(0); //, - map.addOverlay(geoResult); name = geotrack(geoResult['_point'], geoResult); // geoResult['text'] = '<b>' + geoResult['text'] + '.<br> ' + name + '</b>'; map.panTo(geoResult['_point'], { flying: 1 }); // } else { alert(" "); //TODO: - } }); // YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (geocoder, error) { alert(" : " + error); //TODO: - }) }
ええ、何かがGETに来たかどうか(サイトの概念に応じて、そこから来るはずです)を確認し、もしそうなら、探しているアドレスとしてリクエストを使用します。
var get = location.search; if(get != '') { object_address = decodeURI(get.split('?object_address=')[1]); if(object_address==" ") {object_address=""; } else {YMaps.jQuery('#find_nearest_form').submit(); } } else { object_address=''; }
ソースコード全体は、例のリンクを使用して表示できます。
コメントさせていただきます。
*更新*最後に、投稿を編集する方法を見つけたので、すべてを修正したいので、すべてを追加しました。
助けてくれたみんなに感謝します。
メソッドとオブジェクトに関する情報:
api.yandex.ru/maps/jsapi/doc/ref/reference/map.xml
api.yandex.ru/maps/jsapi/doc/ref/reference/geopoint.xml
api.yandex.ru/maps/jsapi/doc/ref/reference/polyline.xml