2

Meteor クライアントで、マップ オブジェクトを定義しました。

Meteor.startup(function () {
  map = L.map('map_canvas').locate({setView: true, maxZoom: 21});
  L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map);
});

Template.xxxx.events、Template.yyy.rendered...でアクセスできるグローバルとして使用します...(それが最善の方法であるかどうかはわかりません)

だからここまでは大丈夫。

ここで、サーバー側でのみ実行できる地理空間クエリを実行する必要があります。

Meteor.startup(function () {
  Meteor.publish("AllMessages", function() {
    lists._ensureIndex( { location : "2d" } );
    var bottomLeftLat = map.getBounds()._southWest.lat;
    var bottomLeftLng = map.getBounds()._southWest.lng;
    var topRightLat = map.getBounds()._northEast.lat;
    var topRightLng = map.getBounds()._northEast.lng;
    return lists.find( { "location": { "$within": { "$box": [ [bottomLeftLng, bottomLeftLat] , [topRightLng, topRightLat] ] } } } );
  });
});

しかし、アプリがクラッシュし、次のようになります。

Exception from sub ZeJzWHdF8xQg57QtF ReferenceError: map is not defined
    at null._handler (app/server/Server.js:4:25)
    at _.extend._runHandler (app/packages/livedata/livedata_server.js:815:31)
    at _.extend._startSubscription (app/packages/livedata/livedata_server.js:714:9)
    at _.extend.protocol_handlers.sub (app/packages/livedata/livedata_server.js:520:12)
    at _.extend.processMessage.processNext (app/packages/livedata/livedata_server.js:484:43)

ロード時間の事ですか?タイムアウトを設定して、クエリを実行する前にマップが読み込まれるまで待つ必要がありますか?

編集これが私が試したもので、うまくいきません

サーバ

Meteor.startup(function () {
  Meteor.publish("AllMessages", function() {
    lists._ensureIndex( { location : "2d" } );
    return lists.find();
  });
});

Meteor.methods({
  getListsWithinBounds: function(bounds) {
    return lists.find( { "location": { "$within": { "$box": [ [bottomLeftLng, bottomLeftLat] , [topRightLng, topRightLat] ] } } } );
  }
});

クライアント

Meteor.startup(function () {
  map = L.map('map_canvas').locate({setView: true, maxZoom: 21});
  L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
  }).addTo(map);
    bounds = {};    
    map.on('locationfound', function(e){ 
      bounds.bottomLeftLat = map.getBounds()._southWest.lat;
      bounds.bottomLeftLng = map.getBounds()._southWest.lng;
      bounds.topRightLat = map.getBounds()._northEast.lat;
      bounds.topRightLng = map.getBounds()._northEast.lng;
      console.log(bounds);
      Meteor.call("getListsWithinBounds", bounds, function(err, result) {
        console.log('call'+result); // should log a LocalCursor pointing to the relevant lists
      });
    });
});
4

2 に答える 2

2

編集:さらに良いことに、カスタムのリアクティブ データ ソースを使用します。ここに小さなチュートリアルを書きました。

古い投稿:

私は似たようなものを実装しました。私のサーバー コードには、次のパブリッシュ関数があります。

// Publish those trails within the bounds of the map view.
Meteor.publish('trails', function(bounds){
 if (bounds && bounds.southWest && bounds.northEast) {
  return Trails.find({'coordinates': {'$within' : 
    { '$box' : [bounds.southWest, bounds.northEast] }
  }}, {
    limit: 100
  });
 }
});

私のクライアント側のコードでは、マップ境界のクライアント側のみのコレクションを保持しています。(基本的に、これは 1 つのドキュメントしか持たないリアクティブ モデルです)。

MapBounds = new Meteor.Collection(null);

そして、クライアントには次のようなサブスクリプションがあります。

// Get trails that are located within our map bounds. 
Meteor.autorun(function () {
 Session.set('loading', true);
  Meteor.subscribe('trails', MapBounds.findOne(), function(){
   Session.set('loading', false);
  }); 
});

最後に、リーフレット クラスは、マップの境界が変更されるたびに境界モデルを更新します。

 onViewChange: function(e){
  var bounds = this.map.getBounds()
    , boundObject = { 
        southWest: [bounds._southWest.lat, bounds._southWest.lng],
        northEast: [bounds._northEast.lat, bounds._northEast.lng] 
      };

  if (MapBounds.find().count() < 1) MapBounds.insert(boundObject);
  else MapBounds.update({}, boundObject);
 }
于 2013-03-19T21:16:38.877 に答える
0

mapクライアントで定義したため、サーバーでは変数を使用できません。Leaflet はクライアント側の API であるため、サーバー上でそのマップ処理を行うこともできません。

特定の境界内のコレクションからリストを返すようにサーバーに要求する場合は、クライアントで境界を計算し、サーバーにそれらの境界を伝えて、サーバーが情報を見つけられるようにする必要があります。これに対する適切なアプローチは、Meteor.method.

サーバー上で、境界を取り、それらの境界内のリストを返すメソッドを定義します。

Meteor.methods({
  getListsWithinBounds: function(bounds) {
    return lists.find({location: {"$within": {"$box": [bounds.bottomLeftLng, bounds.bottomLeftLat], [bounds.topRightLng, bounds.topRightLat]}});
  }
});

次に、クライアントで、サーバーでメソッドを呼び出します。

Meteor.call("getListsWithinBounds", bounds, function(err, result) {
  console.log(result); // should log a LocalCursor pointing to the relevant lists
});
于 2013-03-18T23:30:26.870 に答える