49 #include <boost/unordered_map.hpp>
50 #include <boost/shared_ptr.hpp>
51 #include <boost/iterator.hpp>
52 #include <boost/iterator/transform_iterator.hpp>
55 #include "spatial_math.h"
56 #include "RepastErrors.h"
63 template<
typename T,
typename GPType>
68 boost::shared_ptr<T> ptr;
71 inGrid(
false), point(0) {
79 template<
typename T,
typename GPType>
81 GridPointHolder<T, GPType>*>::value_type, boost::shared_ptr<T> > {
82 boost::shared_ptr<T> operator()(
103 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
111 typedef typename boost::unordered_map<AgentId, GridPointHolder<T, GPType>*,
HashId> AgentLocationMap;
113 AgentLocationMap agentToLocation;
116 CellAccessor cellAccessor;
124 typedef typename AgentLocationMap::iterator LocationMapIter;
125 typedef typename AgentLocationMap::const_iterator LocationMapConstIter;
127 GPTransformer gpTransformer;
130 virtual bool addAgent(boost::shared_ptr<T> agent);
131 virtual void removeAgent(T* agent);
133 LocationMapConstIter locationsBegin()
const {
134 return agentToLocation.begin();
136 LocationMapConstIter locationsEnd()
const {
137 return agentToLocation.end();
147 typedef typename boost::transform_iterator<AgentFromGridPoint<T, GPType> , LocationMapConstIter>
const_iterator;
162 virtual bool getLocation(
const T* agent, std::vector<GPType>& pt)
const;
184 virtual bool moveTo(
const T* agent,
const std::vector<GPType>& newLocation);
210 virtual bool moveTo(
const AgentId&
id,
const std::vector<GPType>& newLocation);
216 virtual std::pair<bool, Point<GPType> >
moveByDisplacement(
const T* agent,
const std::vector<GPType>& displacement);
219 virtual std::pair<bool, Point<GPType> >
moveByVector(
const T* agent,
double distance,
220 const std::vector<double>& anglesInRadians);
268 gpTransformer.translate(location.
coords(), out, displacement.
coords());
272 virtual void transform(
const std::vector<GPType>& location, std::vector<GPType>& out)
const {
273 gpTransformer.transform(location, out);
278 return gpTransformer.isPeriodic();
281 virtual ProjectionInfoPacket* getProjectionInfo(
AgentId id,
bool secondaryInfo =
false, std::set<AgentId>* secondaryIds = 0,
int destProc = -1 );
285 virtual void getAgentsToPush(std::set<AgentId>& agentsToTest, std::map<
int, std::set<AgentId> >& agentsToPush){ }
290 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
292 Grid<T, GPType> (name), gpTransformer(dimensions), dimensions_(dimensions), size_(0) {
294 adder.init(dimensions,
this);
297 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
299 for (LocationMapIter iter = agentToLocation.begin(); iter != agentToLocation.end(); ++iter) {
304 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
305 T* BaseGrid<T, CellAccessor, GPTransformer, Adder, GPType>::get(
const AgentId&
id) {
306 LocationMapConstIter iter = agentToLocation.find(
id);
307 if (iter == agentToLocation.end())
310 return iter->second->ptr.get();
313 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
315 LocationMapConstIter iter = agentToLocation.find(
id);
316 if (iter == agentToLocation.end())
323 if (out.size() != dimensions_.dimensionCount())
324 out.resize(dimensions_.dimensionCount(), 0);
325 holder->point.
copy(out);
330 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
332 return getLocation(agent->getId(), out);
335 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
337 return agentToLocation.find(
id) != agentToLocation.
end();
340 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
342 return moveTo(agent->getId(), newLocation.
coords());
345 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
347 const std::vector<GPType>& newLocation) {
348 return moveTo(agent->getId(), newLocation);
351 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
354 return moveTo(
id, newLocation.
coords());
357 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
359 const std::vector<GPType>& newLocation) {
360 LocationMapIter iter = agentToLocation.find(
id);
362 if (iter == agentToLocation.end())
365 if (newLocation.size() < dimensions_.dimensionCount())
366 throw Repast_Error_3(newLocation.size(), dimensions_.dimensionCount());
368 std::vector<GPType> transformedCoords(newLocation.size(), 0);
369 gpTransformer.transform(newLocation, transformedCoords);
371 if (iter->second->point.coords() == transformedCoords)
return true;
372 return doMove(transformedCoords, iter->second);
375 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
379 if (cellAccessor.put(gpHolder->ptr, pt)) {
380 if (gpHolder->inGrid) {
381 cellAccessor.remove(gpHolder->ptr, gpHolder->point);
384 gpHolder->inGrid =
true;
386 gpHolder->point = pt;
392 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
394 double distance,
const std::vector<double>& anglesInRadians) {
395 if (anglesInRadians.size() != dimensions_.dimensionCount())
396 throw Repast_Error_4(anglesInRadians.size(), dimensions_.dimensionCount());
398 std::vector<GPType> pt = calculateDisplacement<GPType> (dimensions_.dimensionCount(), 0, distance, anglesInRadians);
399 return moveByDisplacement(agent, pt);
402 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
404 const T* agent,
const std::vector<GPType>& displacement) {
405 if (displacement.size() != dimensions_.dimensionCount())
406 throw Repast_Error_5(displacement.size(), dimensions_.dimensionCount());
408 LocationMapIter iter = agentToLocation.find(agent->getId());
409 if (iter == agentToLocation.end())
413 std::vector<GPType> newPos(displacement.size(), 0);
414 gpTransformer.translate(gpHolder->point.
coords(), newPos, displacement);
415 std::vector<GPType> transformedCoords(newPos.size(), 0);
416 gpTransformer.transform(newPos, transformedCoords);
417 if (iter->second->point.coords() == transformedCoords)
418 return std::make_pair(
true,
Point<GPType> (transformedCoords));
419 return std::make_pair(moveTo(agent->getId(), transformedCoords),
Point<GPType> (transformedCoords));
422 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
424 return cellAccessor.get(pt);
427 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
429 std::vector<T*>& out)
const {
430 return cellAccessor.getAll(pt, out);
433 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
438 agentToLocation[agent->getId()] = gp;
439 return adder.add(agent);
442 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
443 void BaseGrid<T, CellAccessor, GPTransformer, Adder, GPType>::removeAgent(T* agent) {
444 LocationMapIter iter = agentToLocation.find(agent->getId());
445 if (iter != agentToLocation.end()) {
446 GridPointHolder<T, GPType>* gp = iter->second;
447 cellAccessor.remove(gp->ptr, gp->point);
449 agentToLocation.erase(iter);
453 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
455 GPType>& pt2)
const {
456 return sqrt(getDistanceSq(pt1, pt2));
459 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
461 GPType>& pt2)
const {
468 if (gpTransformer.isPeriodic()) {
469 double dim = dimensions_.extents(i);
470 double absDiff = ((diff < 0.00) ? (-1.0 * diff) : diff);
471 if (absDiff > dim / 2.0) diff = dim - absDiff;
479 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
481 GPType>& pt2, std::vector<GPType>& out)
const {
487 if (gpTransformer.isPeriodic()) {
488 double dim = dimensions_.extents(i);
489 GPType absDiff = ((diff < 0.00) ? (-1.0 * diff) : diff);
490 if (absDiff > dim / ((GPType) 2)) diff = dim - absDiff;
496 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
498 std::set<AgentId>* secondaryIds,
int destProc){
499 typename AgentLocationMap::const_iterator agentIter = agentToLocation.find(
id);
500 if(agentIter == agentToLocation.end()){
504 return new SpecializedProjectionInfoPacket<GPType>(
id, agentIter->second->point.coords());
509 template<
typename T,
typename CellAccessor,
typename GPTransformer,
typename Adder,
typename GPType>
510 void BaseGrid<T, CellAccessor, GPTransformer, Adder, GPType>::updateProjectionInfo(ProjectionInfoPacket* pip, Context<T>* context){
511 SpecializedProjectionInfoPacket<GPType>* spip =
static_cast<SpecializedProjectionInfoPacket<GPType>*
>(pip);
512 moveTo(spip->id, spip->data);