[mapserver-users] Projection and mapquery

Morten Sickel Morten.Sickel at nrpa.no
Tue Feb 2 07:20:26 EST 2010


OK, i found a workaround to the original problem:

> I presently have a set up in which I plot some measurements on some 
> background maps. Things work fine, but I want to add the possibility 
> to query the measurement data set by clicking on a measurement. The 
> measurements have coordinates in lat lon and I only manage to query 
> those data if I plot the entire map in the same projection. 
(the map should be in utm, I would prefer not having to reproject the measurement locations)

I create a new map object with the layer to be queried, set the projection of the new map object to the same as the queried layer and then I do a queryByPoint on the new map object. This works to get find a object. To plot the query map, I get a unique id for the selected point, do a queryByAttributes on the corresponding layer in the drawn map. 


-- 
Morten Sickel
Norwegian Radiation Protection Authority


=== php code  == some parts removed

// I am querying a map layer called "mobile" 

// I am using smarty templating for my php script, if you don't know that, just consider the 
// $smarty->assign calls as a way to get something printed out.

function pix2geo($mapx,$mapy,$minx,$miny,$maxx,$maxy,$sizex,$sizey)
// calculates geographical coordinates in the map from click coordinates on the image
{					 
	list($miny,$maxy)=array($maxy,$miny); 
	// swaps miny and max y since the coordinates acsends upwards in the map, downwards in the picture
	$geopoint=array();
	foreach( array('x','y') as $dim){
		$p=array();
		foreach(array('map','min','max','size') as $par){
			$name="$par$dim";
			$p[$par]=$$name;
		}
		$geowidth=$p['max']-$p['min'];
		$geopoint[$dim]=$p['map']/$p['size']*$geowidth+$p['min'];
	}
	return(array($geopoint['x'],$geopoint['y']));
}

$map=ms_newMapObj($map_path.'mobilweb.map');

$foundresults=false;
if($_GET['extent']){
	list($minx,$miny,$maxx,$maxy)=explode(" ",$_GET['extent']);
	$map->setextent($minx,$miny,$maxx,$maxy);
}
$clickpoint=ms_newpointObj();
$clickpoint->setXY($_GET['MAP_x']*1,$_GET['MAP_y']*1);
if(!isset($_GET['update'])){
	if($_GET['action']=='QUERY'){
		list($geoX,$geoY)=pix2geo($_GET['MAP_x']*1,$_GET['MAP_y']*1,$minx,$miny,$maxx,$maxy,$map->width,$map->height);
		$geopoint=ms_newpointObj();
		$geopoint->setXY($geoX,$geoY);
		$mapproj=$map->getProjection();
		$layerproj=$map->getlayerbyname('mobil')->getProjection();
		if($mapproj!=$layerproj){
			$oMapproj=ms_newProjectionObj($mapproj);
			$oLayerproj=ms_newProjectionObj($layerproj);
			$geopoint->project($oMapproj, $oLayerproj); 
			// projects the point from the projection of the map to the projection of layer
			$newmap=$map->clone(); // Might be better to make a new object and then add the querylayer to that object
			$newmap->setProjection($layerproj);
			$querymap=$newmap;
		}else{
			$querymap=$map;
		}
		$result=@$querymap->queryByPoint($geopoint, MS_SINGLE , -1);
		if ( $result==MS_FAILURE ) {$smarty->assign('mapmessage','No data found');}
		$layername='mobil'; 
		$layerfield='id'; 
		$oLayer = $querymap->GetLayerByName($layername);
		$numResults = $oLayer->getNumResults();
		if($numResults){
			$foundresults=true;
			$oLayer->open();
			for ($iRes=0; $iRes < $numResults; $iRes++)
			{
				$oRes = $oLayer->getResult($iRes);
				$oShape = $oLayer->getShape($oRes->tileindex,$oRes->shapeindex);
				$result=$oShape->values[$layerfield];
				$smarty->assign('queryresult',$result);
				$smarty->assign('querytime',date("Y.m.d H:i:s",$oShape->values['utctime']));
				$oShape->free;
			}
			$oLayer->close;
			if($querymap!=$map){ // Must transfer the information back to the map that is to be plotted
				// NB, the field I'm using is the primary index in the database table, i know it is unique.
				$oLayer=$map->GetLayerByName($layername);
				$oLayer->queryByAttributes($layerfield,$result,MS_SINGLE);
			}
		}
		
	}
}
	



More information about the mapserver-users mailing list