/*****************************************************************************/
/* importshp.cpp - shape file importer */
/* */
/* Copyright (C) 2011 Rallaz, rallazz@gmail.com */
/* */
/* This library is free software, licensed under the terms of the GNU */
/* General Public License as published by the Free Software Foundation, */
/* either version 2 of the License, or (at your option) any later version. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see . */
/*****************************************************************************/
#include
#include
#include
#include
#include
#include
#include "importshp.h"
/*TODO
complete readAttributes
void readPolyline(DBFHandle dh, int i);
void readPolylineC(DBFHandle dh, int i);
void readMultiPolyline(DBFHandle dh, int i);
SHPT_MULTIPOINT
*/
PluginCapabilities ImportShp::getCapabilities() const
{
PluginCapabilities pluginCapabilities;
pluginCapabilities.menuEntryPoints
<< PluginMenuLocation("File/Import", tr("shape file"));
return pluginCapabilities;
}
QString ImportShp::name() const
{
return (tr("shape file"));
}
void ImportShp::execComm(Document_Interface *doc,
QWidget *parent, QString /*cmd*/)
{
dibSHP pdt(parent);
int result = pdt.exec();
if (result == QDialog::Accepted)
pdt.procesFile(doc);
}
/*****************************/
dibSHP::dibSHP(QWidget *parent) : QDialog(parent)
{
QVBoxLayout *mainLayout = new QVBoxLayout;
QPushButton *filebut = new QPushButton(tr("File..."));
fileedit = new QLineEdit();
QHBoxLayout *lofile = new QHBoxLayout;
lofile->addWidget(filebut);
lofile->addWidget(fileedit);
lofile->setSizeConstraint(QLayout::SetFixedSize);//ni caso
mainLayout->addLayout(lofile);
QLabel *formatlabel = new QLabel(tr("File type:"));
formattype = new QLabel(tr("Unknoun"));
QHBoxLayout *loformat = new QHBoxLayout;
loformat->addWidget(formatlabel);
loformat->addWidget(formattype);
loformat->addStretch();
mainLayout->addLayout(loformat);
QGroupBox *laybox = new QGroupBox(tr("Layer"));
radiolay1 = new QRadioButton(tr("Current"));
QRadioButton *radiolay2 = new QRadioButton(tr("From data:"));
layerdata = new QComboBox();
radiolay1->setChecked(true);
QHBoxLayout *laylayout = new QHBoxLayout;
laylayout->addWidget(radiolay1);
laylayout->addWidget(radiolay2);
laylayout->addWidget(layerdata);
laylayout->addStretch(0);
laybox->setLayout(laylayout);
mainLayout->addWidget(laybox);
QGroupBox *colbox = new QGroupBox(tr("Color"));
radiocol1 = new QRadioButton(tr("Current"));
QRadioButton *radiocol2 = new QRadioButton(tr("From data:"));
colordata = new QComboBox();
radiocol1->setChecked(true);
QHBoxLayout *collayout = new QHBoxLayout;
collayout->addWidget(radiocol1);
collayout->addWidget(radiocol2);
collayout->addWidget(colordata);
collayout->addStretch(1);
colbox->setLayout(collayout);
mainLayout->addWidget(colbox);
QGroupBox *ltypebox = new QGroupBox(tr("Line type"));
radioltype1 = new QRadioButton(tr("Current"));
QRadioButton *radioltype2 = new QRadioButton(tr("From data:"));
ltypedata = new QComboBox();
radioltype1->setChecked(true);
QHBoxLayout *ltypelayout = new QHBoxLayout;
ltypelayout->addWidget(radioltype1);
ltypelayout->addWidget(radioltype2);
ltypelayout->addWidget(ltypedata);
ltypelayout->addStretch(1);
ltypebox->setLayout(ltypelayout);
mainLayout->addWidget(ltypebox);
QGroupBox *lwidthbox = new QGroupBox(tr("Width"));
radiolwidth1 = new QRadioButton(tr("Current"));
QRadioButton *radiolwidth2 = new QRadioButton(tr("From data:"));
lwidthdata = new QComboBox();
radiolwidth1->setChecked(true);
QHBoxLayout *lwidthlayout = new QHBoxLayout;
lwidthlayout->addWidget(radiolwidth1);
lwidthlayout->addWidget(radiolwidth2);
lwidthlayout->addWidget(lwidthdata);
lwidthlayout->addStretch(1);
lwidthbox->setLayout(lwidthlayout);
mainLayout->addWidget(lwidthbox);
pointbox = new QGroupBox(tr("Point"));
radiopoint1 = new QRadioButton(tr("as Point"));
QRadioButton *radiopoint2 = new QRadioButton(tr("as Label:"));
pointdata = new QComboBox();
radiopoint1->setChecked(true);
QHBoxLayout *pointlayout = new QHBoxLayout;
pointlayout->addWidget(radiopoint1);
pointlayout->addWidget(radiopoint2);
pointlayout->addWidget(pointdata);
pointlayout->addStretch(1);
pointbox->setLayout(pointlayout);
mainLayout->addWidget(pointbox);
QHBoxLayout *loaccept = new QHBoxLayout;
QPushButton *acceptbut = new QPushButton(tr("Accept"));
QPushButton *cancelbut = new QPushButton(tr("Cancel"));
loaccept->addStretch();
loaccept->addWidget(acceptbut);
loaccept->addWidget(cancelbut);
loaccept->addStretch();
mainLayout->addLayout(loaccept);
setLayout(mainLayout);
readSettings();
updateFile();
connect(cancelbut, SIGNAL(clicked()), this, SLOT(reject()));
connect(acceptbut, SIGNAL(clicked()), this, SLOT(checkAccept()));
connect(filebut, SIGNAL(clicked()), this, SLOT(getFile()));
connect(fileedit, SIGNAL(editingFinished()), this, SLOT(updateFile()));
}
void dibSHP::checkAccept()
{
writeSettings();
accept();
}
void dibSHP::getFile()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select file"),
fileedit->text(), "Shapefiles *.shp(*.shp)");
fileedit->setText(fileName);
updateFile();
}
void dibSHP::updateFile()
{
QString fileName = fileedit->text();
int num_ent, st, num_field;
double min_bound[4], max_bound[4];
QStringList txtformats;
char field_name[12];
QFileInfo fi = QFileInfo(fileName);
if (fi.suffix() != "shp") return;
QString file = fi.canonicalFilePath ();
if (file.isEmpty()) return;
SHPHandle sh = SHPOpen( file.toLocal8Bit(), "rb" );
SHPGetInfo( sh, &num_ent, &st, min_bound, max_bound );
SHPClose( sh );
DBFHandle dh = DBFOpen( file.toLocal8Bit(), "rb" );
num_field = DBFGetFieldCount( dh );
for( int i = 0; i < num_field; i++ ) {
DBFGetFieldInfo( dh, i, field_name,NULL, NULL);
txtformats << field_name;
}
DBFClose( dh );
txtformats.sort();
layerdata->clear();
layerdata->addItems(txtformats);
colordata->clear();
colordata->addItems(txtformats);
ltypedata->clear();
ltypedata->addItems(txtformats);
lwidthdata->clear();
lwidthdata->addItems(txtformats);
pointdata->clear();
pointdata->addItems(txtformats);
switch (st) {
case SHPT_POINT:
formattype->setText(tr("Point"));
pointbox->setDisabled(false);
break;
case SHPT_POINTM:
formattype->setText(tr("Point+Measure"));
pointbox->setDisabled(false);
break;
case SHPT_POINTZ: //3d point
formattype->setText(tr("3D Point"));
pointbox->setDisabled(false);
break;
case SHPT_MULTIPOINT:
formattype->setText(tr("Multi Point"));
pointbox->setDisabled(false);
break;
case SHPT_MULTIPOINTM:
formattype->setText(tr("Multi Point+Measure"));
pointbox->setDisabled(false);
break;
case SHPT_MULTIPOINTZ:
formattype->setText(tr("3D Multi Point"));
pointbox->setDisabled(false);
break;
case SHPT_ARC:
formattype->setText(tr("Arc"));
pointbox->setDisabled(true);
break;
case SHPT_ARCM:
formattype->setText(tr("Arc+Measure"));
pointbox->setDisabled(true);
break;
case SHPT_ARCZ:
formattype->setText(tr("3D Arc"));
pointbox->setDisabled(true);
break;
case SHPT_POLYGON:
formattype->setText(tr("Poligon"));
pointbox->setDisabled(true);
break;
case SHPT_POLYGONM:
formattype->setText(tr("Poligon+Measure"));
pointbox->setDisabled(true);
break;
case SHPT_POLYGONZ:
formattype->setText(tr("3D Poligon"));
pointbox->setDisabled(true);
break;
case SHPT_MULTIPATCH:
formattype->setText(tr("Multipatch"));
pointbox->setDisabled(true);
break;
case SHPT_NULL:
default:
formattype->setText(tr("Unknoun"));
pointbox->setDisabled(true);
break;
}
}
void dibSHP::procesFile(Document_Interface *doc)
{
int num_ent, st;
double min_bound[4], max_bound[4];
currDoc = doc;
QFileInfo fi = QFileInfo(fileedit->text());
if (fi.suffix() != "shp") {
QMessageBox::critical ( this, "Shapefile", QString(tr("The file %1 not have extension .shp")).arg(fileedit->text()) );
return;
}
if (!fi.exists() ) {
QMessageBox::critical ( this, "Shapefile", QString(tr("The file %1 not exist")).arg(fileedit->text()) );
return;
}
QString file = fi.canonicalFilePath ();
SHPHandle sh = SHPOpen( file.toLocal8Bit(), "rb" );
SHPGetInfo( sh, &num_ent, &st, min_bound, max_bound );
DBFHandle dh = DBFOpen( file.toLocal8Bit(), "rb" );
if (radiolay1->isChecked()) {
layerF = -1;
attdata.layer = currDoc->getCurrentLayer();
} else {
layerF = DBFGetFieldIndex( dh, (layerdata->currentText()).toLatin1().data() );
layerT = DBFGetFieldInfo( dh, layerF, NULL, NULL, NULL );
}
if (radiocol1->isChecked())
colorF = -1;
else {
colorF = DBFGetFieldIndex( dh, (colordata->currentText()).toLatin1().data() );
colorT = DBFGetFieldInfo( dh, colorF, NULL, NULL, NULL );
}
if (radioltype1->isChecked())
ltypeF = -1;
else {
ltypeF = DBFGetFieldIndex( dh, (ltypedata->currentText()).toLatin1().data() );
ltypeT = DBFGetFieldInfo( dh, ltypeF, NULL, NULL, NULL );
}
if (radiolwidth1->isChecked())
lwidthF = -1;
else {
lwidthF = DBFGetFieldIndex( dh, (lwidthdata->currentText()).toLatin1().data() );
lwidthT = DBFGetFieldInfo( dh, lwidthF, NULL, NULL, NULL );
}
if (radiopoint1->isChecked())
pointF = -1;
else {
pointF = DBFGetFieldIndex( dh, (pointdata->currentText()).toLatin1().data() );
pointT = DBFGetFieldInfo( dh, pointF, NULL, NULL, NULL );
}
currlayer =currDoc->getCurrentLayer();
for( int i = 0; i < num_ent; i++ ) {
sobject= NULL;
sobject = SHPReadObject( sh, i );
if (sobject) {
switch (sobject->nSHPType) {
case SHPT_NULL:
break;
case SHPT_POINT:
case SHPT_POINTM: //2d point with measure
case SHPT_POINTZ: //3d point
readPoint(dh, i);
break;
case SHPT_MULTIPOINT:
case SHPT_MULTIPOINTM:
case SHPT_MULTIPOINTZ:
break;
case SHPT_ARC:
case SHPT_ARCM:
case SHPT_ARCZ:
readPolyline(dh, i);
break;
case SHPT_POLYGON:
case SHPT_POLYGONM:
case SHPT_POLYGONZ:
readPolylineC(dh, i);
case SHPT_MULTIPATCH:
readMultiPolyline(dh, i);
default:
break;
}
SHPDestroyObject(sobject);
}
}
SHPClose( sh );
DBFClose( dh );
currDoc->setLayer(currlayer);
}
void dibSHP::readPoint(DBFHandle dh, int i){
Plug_Entity *ent =NULL;
QHash data;
if (pointF < 0) {
ent = currDoc->newEntity(DPI::POINT);
ent->getData(&data);
} else {
ent = currDoc->newEntity(DPI::TEXT);
ent->getData(&data);
data.insert(DPI::TEXTCONTENT, DBFReadStringAttribute( dh, i, pointF ) );
}
data.insert(DPI::STARTX, *(sobject->padfX));
data.insert(DPI::STARTY, *(sobject->padfY));
readAttributes(dh, i);
data.insert(DPI::LAYER, attdata.layer);
ent->updateData(&data);
currDoc->addEntity(ent);
}
void dibSHP::readPolyline(DBFHandle dh, int i){
int maxPoints;
Plug_Entity *ent =NULL;
QHash data;
QList vl;
readAttributes(dh, i);
data.insert(DPI::LAYER, attdata.layer);
for( int i = 0; i < sobject->nParts; i++ ) {
if ( (i+1) < sobject->nParts) maxPoints = sobject->panPartStart[i+1];
else maxPoints = sobject->nVertices;
vl.clear();
for( int j = sobject->panPartStart[i]; j < maxPoints; j++ ) {
vl.append( Plug_VertexData( QPointF(sobject->padfX[j],sobject->padfY[j]), 0.0) );
}
if (vl.size() > 2 ) {
ent = currDoc->newEntity(DPI::POLYLINE);
ent->updateData(&data);
currDoc->addEntity(ent);
ent->updatePolylineData(&vl);
}
}
}
void dibSHP::readPolylineC(DBFHandle dh, int i){
}
void dibSHP::readMultiPolyline(DBFHandle dh, int i){
}
void dibSHP::readAttributes(DBFHandle dh, int i){
if (layerF >= 0) {
attdata.layer = DBFReadStringAttribute( dh, i, layerF );
currDoc->setLayer(attdata.layer);
}
/* if (colorF >= 0)
readColor(dh, i);
if (ltypeF >= 0)
readLType(dh, i);
if (lwidthF >= 0)
readWidth(dh, i);*/
}
dibSHP::~dibSHP()
{
/* while (!dataList.isEmpty())
delete dataList.takeFirst();*/
}
void dibSHP::readSettings()
{
QString str;
QSettings settings(QSettings::IniFormat, QSettings::UserScope, "LibreCAD", "importshp");
QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
QSize size = settings.value("size", QSize(325,425)).toSize();
str = settings.value("lastfile").toString();
fileedit->setText(str);
resize(size);
move(pos);
}
void dibSHP::writeSettings()
{
QSettings settings(QSettings::IniFormat, QSettings::UserScope, "LibreCAD", "importshp");
settings.setValue("pos", pos());
settings.setValue("size", size());
settings.setValue("lastfile", fileedit->text());
}
Q_EXPORT_PLUGIN2(importshp, ImportShp);