C++/GIS

ShapeLib(Shapefile C Library) 사용

3zzang 2023. 2. 4. 22:54

ShapeLib 이란 ?

C언어로 ESRI Shapefile 및 관련 속성파일(.dbf)를 읽기, 쓰기, 업데이트(제한된 범위까지)를 가능하게 하는 C Library

라이센스 : LGPL, MIT
http://shapelib.maptools.org/license.html

 

Shapelib License

License The source for the Shapefile C Library is (c) 1998 Frank Warmerdam, and released under the following conditions. The intent is that anyone can do anything with the code, but that I do not assume any liability, nor express any warranty for this code

shapelib.maptools.org

해당 라이브러리 페이지의 설명에 따르면 Shapelib 1.2.6부터 라이브러리의 핵심 부분은 LGPL, MIT 스타일 두 가지 가능한 라이선스로 제공된다고 합니다.
선택 가능 하다는 식으로 써있는데 이게 무슨 말인지는 이해가 안됩니다 .. ㅠㅠ

(참고)
LGPL 2.1:
- Libarary의 일부를 수정하는 경우 수정한 Library를 LPGL에 의해 소스코드 공개
- LGPL Library에 응용프로그램을 링크 시킬(Static과 Dynamic Linking 모두) 경우 해당 응용프로그램의 소스를 공개할 필요 없음. 다만 사용자가 Library 수정 후 동일한 실행 파일을 생성할 수 있도록 Static Linking시에는 응용프로그램의 Object Code를 제공해야 함
- 특허의 경우 GPL과 동일함
출처 : https://openbee.kr/422 , http://wiki.kldp.org/wiki.php/OpenSourceLicenseGuide#s-2.2

라이브러리 설치 및 빌드 그리고 라이브러리 연결

http://download.osgeo.org/shapelib/ : 다운로드 페이지

https://mamm.tistory.com/entry/MFC-shapefileshapeLib-150-c-오픈소스-라이브러리-컴파일

 

[MFC] shapefile(shapeLib-1.5.0) c++ 오픈소스 라이브러리 컴파일하기

visualstudio 2008 MFC C언어로 shape 파일을 읽기 위해 라이브러리를 찾던 중, 발견한 http://shapelib.maptools.org/ 사이트는 찾았지만, 압축 풀고 나서 어떻게해야할지 헤맸다.. windows 환경이라 shapelib-1.5.0.zip

mamm.tistory.com

위의 분이 정리를 정말 잘해주셔서 이대로 했더니 쉽게 설치 및 빌드를 할 수 있었습니다! 정말 감사합니다 :)

혹시 저와 같이 에러가 나시는 분들에게 추가를 하자면,
C/C++> 전처리기 >전처리기 정의 > _CRT_SECURE_NO_WARNINGS 추가를 해서 빌드했습니다.

샘플 코드 :

Shapelib 예시 코드 : Basic usage of shapelib · GitHub

 

Basic usage of shapelib

Basic usage of shapelib. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

//By Tim Sheerman-Chase, released under CC0
//Compile: g++ shapelib_example.cpp -lshp -o shapelib_example

#include <iostream>
#include <vector>
#include <string>
#include "shapefil.h"
using namespace std;

int main(int argc, const char **argv)
{
	string fina = "map.shp";
	SHPHandle h = SHPOpen(fina.c_str(), "rb");

	if(h==nullptr)
	{
		cout << "Failed to open shp" << endl;
		return -1;
	}

	int nEntities=0, nShapeType=0;

	SHPGetInfo(h, &nEntities, &nShapeType, nullptr, nullptr);

	cout << nEntities << endl;
	for(int i=0; i<nEntities; i++)
	{
		SHPObject *obj = SHPReadObject(h, i);
		if(obj == nullptr) continue;

		int &shpType = obj->nSHPType; //Shape Type (SHPT_* - see list above)
		int &shapeId = obj->nShapeId; //Shape Number (-1 is unknown/unassigned)

		int &parts = obj->nParts; //# of Parts (0 implies single part with no info)
		int *panPartStart = obj->panPartStart;  //Start Vertex of part
		int *panPartType = obj->panPartType;   //Part Type (SHPP_RING if not SHPT_MULTIPATCH)
		int &vertices = obj->nVertices; //Vertex list 

		double &xMin = obj->dfXMin; //Bounds in X, Y, Z and M dimensions
		double &yMin = obj->dfYMin;
		double &zMin = obj->dfZMin;

		double &xMax = obj->dfXMax;
		double &yMax = obj->dfYMax;
		double &zMax = obj->dfZMax;
		cout << SHPTypeName(shpType) << "," << xMin << "," << xMax << "," << yMin << "," << yMax << endl;
		cout << i << "," << vertices << "," << parts << endl;

		std::vector<int> partStart, partType;
		for(int k=0; k<parts; k++)
		{
			partStart.push_back(panPartStart[k]);
			partType.push_back(panPartType[k]);
			//cout << panPartStart[k] << "," << SHPPartTypeName(panPartType[k]) << endl;
		}

		int part = -1;
		for(int j=0; j<vertices; j++)
		{
			if((part+1) < partStart.size() and partStart[part+1] == j)
				part ++;
			int pt = -1;
			if(part >= 0)
				pt = partType[part];
			//cout << part << "," << obj->padfX[j] << "," << obj->padfY[j] << "," << obj->padfZ[j] << endl;
			//cout << SHPPartTypeName(pt) << endl;
		}

		SHPDestroyObject(obj);
	}

	SHPClose(h);

	return 0;
}

위의 샘플코드를 돌렸을 때 출력값이 잘 나오면 라이브러리 연결이 성공한 겁니다!
GIS ... 화이팅 ...