⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 maplist.cpp

📁 这是一个GPS接收定位的原代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "gpslib.h"
#include <dstring.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <qpixmap.h>


class maplist: public list_of<mapinfo>{
public:
	maplist():mrp(0){}
	~maplist();
	const char *readmapdata(const char *mapname);
	// Messy iterator-like function. Returns pointer to
	// maps which match
	mapinfo * locatemap(double lat, double longit);
	const mapinfo * locatemap(const char *cp);
	// If a map was located, here's the gen
	const mapinfo *mp()	{ return mrp; }
   void clear(){list_of<mapinfo>::clear(); mrp = 0;}
private:
	// last item found by locatemap (if any)
	mapinfo *mrp;
} mapinfolist;

int initmaplist(const char *mapname){
	mapinfolist.clear();
	const char *cp = mapinfolist.readmapdata(mapname);
	if(cp){
		printwhinge("Error Reading Map Data: %s", cp);
      return 0;
	}
	return 1;
}

double requestedscale = 0;
void locatescale(double pixperdegn){
	requestedscale = pixperdegn;
}

int enumeratemaps(double lat, double longit, char *namep, int *namelen, double *nscalep, double *escalep){
	const mapinfo *mp = mapinfolist.locatemap(lat, longit);
	if(mp){
		if(namep) strcpy(namep, mp->name.cstring());
		if(namelen) *namelen = mp->name.nchars();
		if(nscalep) *nscalep = mp->pixperdegheight;
		if(escalep) *escalep = mp->pixperdegwidth;
		return 1;
	}
	return 0;
}

// locatemap scans for candidate maps, returning a "best" fit. Here
// we remember the scales found so that other options can be shown
sortable_list_of<double>nscalesfound;

// Call enumeratescales if locatemap has returned true. Returns
// available scales (pix per deg N)
void enumeratescales(list_of<double> &lodr){
	lodr.clear();
	const ne = nscalesfound.element_count();

	// return in reverse order
	for(int i = ne-1; i >= 0; i--){
		lodr += nscalesfound[i];
	}
}

int locatemap(double lat, double longit, String &name, double &nscale, double &escale){
	if(requestedscale == 0){
		const mapinfo *mp = mapinfolist.locatemap(lat, longit);
		if(mp){
			name = mp->name;
			nscale = mp->pixperdegheight;
			escale = mp->pixperdegwidth;
			return 1;
		}
		return 0;
	}
	const mapinfo *mp = locatemapinfo(lat, longit);
	if(mp == 0)
		return 0;
	name = mp->name;
	nscale = mp->pixperdegheight;
	escale = mp->pixperdegwidth;
	return 1;
}

const mapinfo * locatemapinfo(double lat, double longit){
	if(requestedscale == 0)
		return mapinfolist.locatemap(lat, longit);

	// Requestedscale isn't zero - first find 'best' scale, then of all maps
	// within 5%, return the one with the nearest centre point
	nscalesfound.clear();
	// char buff[512];
	mapinfo *mip;
	if(verbose)printf("locatemapinfo, requested scale is %f\n", requestedscale);

	double bestdiff = -100;
	// For each map that contains the desired point
	while((mip = mapinfolist.locatemap(lat, longit)) != 0){
		double thisdiff = fabs(requestedscale-mip->pixperdegheight);
		if(bestdiff < 0 || thisdiff < bestdiff)
			bestdiff = thisdiff;

		// gotalready tells us if we have this approximately this scale in the list
		int gotalready = 0;
		for(int i = 0; i < nscalesfound.element_count(); i++){
			if(fabs(nscalesfound[i]-mip->pixperdegheight) < mip->pixperdegheight/20){
				mip->scalefamily = nscalesfound[i];
				gotalready++;
				break;
			}
		}
		if(!gotalready){
			nscalesfound += mip->pixperdegheight;
			mip->scalefamily = mip->pixperdegheight;
			if(verbose)printf("Adding %f to scale list\n", mip->pixperdegheight);
		}
	}
	nscalesfound.sort();
	if(verbose)printf("Located maps with %d different scales\n", nscalesfound.element_count());

	const mapinfo *mp = 0;
	double bestmiddiff = -100;
	while((mip = mapinfolist.locatemap(lat, longit)) != 0){
		double thisdiff = fabs(requestedscale-mip->pixperdegheight);
		// printf("map scale %f bestdiff %f, thisdiff %f\n", mip->pixperdegheight, bestdiff, thisdiff);
		if(fabs(thisdiff-bestdiff) <= bestdiff/20){
			// prepared to use this one
			// printf("%f within range, family %f\n", thisdiff-bestdiff, mip->scalefamily);
			double latdiff = lat-(mip->latmin+(mip->latmax-mip->latmin)/2);
			double longdiff = longit-(mip->longmin+(mip->longmax-mip->longmin)/2);
			double distance = sqrt(latdiff*latdiff+(longdiff*longdiff));
			if(bestmiddiff < 0 || distance < bestmiddiff){
				// mip->requestedscale = requestedscale;
				mp = mip;
				bestmiddiff = distance;
				// strcpy(buff, mip->name.cstring());
			}
		}
	}
	return mp;

}

#ifdef BITMAP
class bitmap{
public:
	enum howget{full, justinfo};
	bitmap(const char *fname, howget get=justinfo);
	bitmap();
	~bitmap();
	int reload(const string &fname);
	int isvalid()const			{ return vf; }
	long height()const		{ return vf ? dibpixheight : 0;}
	long width()const		{ return vf ? dibpixwidth : 0;}
	// drawon a window
	int drawon(int hwnd, int bmx, int bmy, int windx, int windy, int width, int height);
private:
	int vf;					// validflag
	char huge *bmdp;		// the data pointer whilst reading from file
	long dibpixwidth, dibpixheight;	// pixels w/h
	unsigned long bits;		// offset into bmdp where the bits live
	int hbitmap;
	// we can't copy these things around, sorry
	bitmap(const bitmap&);
	void operator =(const bitmap&);
	void doload(const char *fname, howget);
};

inline int bitmap::reload(const string &fname){
	doload(fname.cstring(), full);
	return vf;
}

int showmap(const char *name, double midlat, double midlong, int hwnd){
	const mapinfo *mip = mapinfolist.locatemap(name);
	if(mip == 0){
		MessageBox(0, "Requested map name not found in showmap", name,  MB_ICONSTOP);
		return 0;
	}
	// Bitmap cache
	static string mapfilename;
	static bitmap bm;
	if(mapfilename != name){
   	mapfilename = name;
		bm.reload(mapfilename);
	}

	if(!bm.isvalid()){
		MessageBox(0, "Requested bitmap invalid in showmap", name,  MB_ICONSTOP);
		return 0;
	}
	if(midlat < mip->latmin || midlat > mip->latmax || midlong < mip->longmin || midlong > mip->longmax){
		MessageBox(0, "midlat/long out of range!", "showmap", MB_ICONSTOP);
      return 0;
	}
	RECT r;
	GetClientRect(hwnd, &r);
	// Locate the pixel within the bitmap which corresponds to midlat/long
	// This was originally done by extrapolating lat/long figures, but that
	// doesn't work too well because of projection errors (NGR grid does not
	// follow lat/long very well).
	int midlatpix, midlongpix;
	if(mip->osproj){
		double east=0, north=0;
		cvtongr(midlat, midlong, 0, &east, &north);
		midlatpix = (mip->northmax-north)*mip->pixpermetreheight;
		midlongpix = (east-mip->eastmin)*mip->pixpermetrewidth;
	}else{
		midlatpix = (mip->latmax-midlat)*mip->pixperdegheight;
		midlongpix = (midlong-mip->longmin)*mip->pixperdegwidth;
	}
	// Adjust offsets within pixel regions
	int wndstartx, wndstarty, mapstartx, mapstarty;
	// work out where on the window the left and top map edges lie - adjust
	// if outside
	wndstartx = r.right/2-midlongpix;
	wndstarty = r.bottom/2-midlatpix;
	mapstartx = 0; mapstarty = 0;
	if(wndstartx < 0){
		mapstartx -= wndstartx;
		wndstartx = 0;
	}
	if(wndstarty < 0){
		mapstarty -= wndstarty;
		wndstarty = 0;
	}
	// and now the drawing width and height
	int dwidth, dheight;
	dwidth = r.right - wndstartx;
	dheight = r.bottom - wndstarty;
	if(dwidth > mip->pixwidth-mapstartx)
		dwidth = int(mip->pixwidth-mapstartx);
	if(dheight > mip->pixheight-mapstarty)
		dheight = int(mip->pixheight-mapstarty);
#if REPORTMAP
	char msgbuff[512];
	sprintf(msgbuff, "mapstartx %d, mapstarty %d, wndstartx %d, wndstarty %d, width %d, height %d",
				mapstartx, mapstarty, wndstartx, wndstarty, dwidth, dheight);
	MessageBox(0, msgbuff, "showmap", MB_ICONSTOP);
#endif
	return bm.drawon(hwnd, mapstartx, mapstarty, wndstartx, wndstarty, dwidth, dheight);
}

#endif

void mapinfo::print()const{
	printf("mapinfo: map %s, longmin %f longmax %g latmin %g latmax %g\n",
		name.cstring(), longmin, longmax, latmin, latmax);
	printf("eastmin %g, eastmax %g, northmin %g, northmax %g\n", eastmin, eastmax, northmin, northmax);
	printf("pixwidth %ld, pixheight %ld, pixperdegwidth %g, pixperdegheight %g\n", pixwidth, pixheight, pixperdegwidth, pixperdegheight);
	printf("pixpermetrewidth %g, pixpermetreheight %g\n",pixpermetrewidth, pixpermetreheight);
}

mapinfo * maplist::locatemap(double lat, double longit){
	static counter;
	while(counter < element_count()){
		mapinfo &mr = operator[](counter);
		counter++;
		if(lat < mr.latmax && lat > mr.latmin && longit < mr.longmax && longit > mr.longmin){
			mrp = &mr;
			return mrp;
		}
	}
	counter = 0;
	mrp = 0;
	return 0;
}

const mapinfo * maplist::locatemap(const char *cp){
	for (int counter = 0; counter < element_count(); counter++){
		mapinfo &mr = operator[](counter);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -