Illustrator教程Adobe Illustrator CS4地图插件开发
小标 2018-04-25 来源 : 阅读 2016 评论 0

摘要:在Illustrator教程中,我们知道Adobe Illustrator的插件,在Windows系统下是采用的传统的动态链接库的形式,只不过是以aip作为后缀名。框架程序应该是用LoadLibrary函数将插件加入到程序模块中,至于插件的加载顺序需要参考Adobe Illustrator教程开发帮助文档。

Illustrator教程Adobe Illustrator CS4地图插件开发

 

在Illustrator教程中,我们知道Adobe Illustrator的插件,在Windows系统下是采用的传统的动态链接库的形式,只不过是以aip作为后缀名。框架程序应该是用LoadLibrary函数将插件加入到程序模块中,至于插件的加载顺序需要参考Adobe Illustrator教程开发帮助文档。

大概是2012年的3月,我着手开发AdobeIllustrator CS4下的地图插件,一边了解Adobe Illustrator的架构体系,一边开发地图插件。

Adobe Illustrator的插件,在Windows系统下是采用的传统的动态链接库的形式,只不过是以aip作为后缀名。框架程序应该是用LoadLibrary函数将插件加入到程序模块中,至于插件的加载顺序需要参考Adobe Illustrator的开发帮助文档。

Adobe Illustrator提供的开发框架中的dll导出函数如下,它是插件与框架交互的通道。

extern "C" ASAPIASErr PluginMain(char* caller, char* selector, void* message);

采用的消息分流器,caller和selector提供的消息分流的依据,message中提供了消息的详细数据。框架将各种消息传递给插件,插件根据需要进行处理。

知道了这些可以开始地图插件的开发了。我的开发目标是:在Illustrator中提供一个地图编辑的良好支持。平面设计软件,优势在于用户群广,图形展示优雅,用户交互体验好,但缺乏一些专业工具。GIS软件应该来说在图形展示和用户体验上还是不能和平面设计软件相比的,好长时间没有使用过GIS数据处理软件了,不知道现在界面还是不是那么丑,支持地图编辑的效果好不好。总结的来说开发任务很简单,将GIS数据转入Adobe Illustrator制作成地图文档即可,并提供专业工具。

在最开始的开发中,我选择了自己的先前的小型的GIS内核,主要包括文件GIS数据、图形、属性、序列化、格式化,并写了shp的转换代码。后来我将GDAL的OGR部分的代码维护进入地图插件工程取代了原有的GIS模块。

转入中,包括地图信息存取、地图图层信息的存取、要素的存取。其中要素存储包括创建art和存储属性,如构建线状art如下(注意坐标先前根据地图比例尺信息已经转为图面坐标了):

AIArtHandle MdRender::DrawLineString(int nCount, AIReal *pData, boolbClosed)
{
         AIArtHandle art = nil;
         sAIArt->NewArt(kPathArt,kPlaceAboveAll, nil, &art);
         sAIPath->SetPathSegmentCount(art,(short)nCount);
         AIPathSegment *segment= new AIPathSegment[nCount];
         for(int i = 0; i <nCount; i++)
         {
                   segment[i].p.h= pData[i * 2];
                   segment[i].p.v= pData[i * 2 + 1];
                   segment[i].in= segment[i].out = segment[i].p;
                   segment[i].corner= true;
         }       
         sAIPath->SetPathSegments(art,0, nCount, segment);
         delete[] segment;
         if(bClosed)
         {
                   sAIPath->SetPathClosed(art,true);
         }
         return art;
}

下面是存储对应的属性:

ASErr MdTransition::SaveFeature(AIArtHandle art, OGRFeature*pFeature)
{
         OGRGeometry*pGeometryRef = pFeature->GetGeometryRef();
         int nWkbSize =pGeometryRef->WkbSize();
         byte *pWkb = NULL;
         if(nWkbSize > 0)
         {
                   pWkb = newbyte[nWkbSize];
                   pGeometryRef->exportToWkb(wkbNDR,pWkb); //使用小字节序
         }
         BinaryArchive archive;
         fSerialize.Serialize(pFeature,archive);
 
         AIDictionaryRef dic =NULL;
         sAIArt->GetDictionary(art,&dic);
         sAIDictionary->SetBinaryEntry(dic,fArtGeometrykey, (void*)pWkb, (ASInt32)nWkbSize);
         sAIDictionary->SetBinaryEntry(dic,fArtAttributeKey, archive.GetData(), archive.GetSize());
         sAIDictionary->Release(dic);
 
         return kNoErr;
}

所有数据都进行文档后。我开发了一个简易的查询功能,但是在GDAL加入后,我弃用了查询。查询使用ADM并提供解析类似sql语句功能,还是具有实际意义,这里还是分享一下开发方法。

ADM是Adobe提供的一套跨平台的用户界面,使用ADM可以在Illustrator中开发出专业的图形界面。我的查询面板继承了Illustrator SDK提供的BaseADMDialog,提供了一个对话框样式的面板。下面的代码可以大概给出一个查询面板构建与使用的主要逻辑:

QueryDialog::QueryDialog(SPPluginRef pluginRef)
:BaseADMDialog()
{
         BaseADMDialog::Create(pluginRef, "NFMDQueryDialog",
                   IDD_DLG_QUE,kADMTabbedFloatingDialogStyle, 0 );
}
ASErr QueryDialog::Init()
{
         ASErr error =BaseADMDialog::Init();
 
         ADMDialogRef dialog =this->GetDialogRef();
         ADMItemRef item = nil;
         item =sADMDialog->GetItem( dialog, IDC_EDIT_QUE );
         sADMItem->Enable(item, false );           
         sADMItem->SetTrackProc(item, QueryTrackProc );
         sADMItem->SetMask(item, kADMKeyStrokeMask ); //Track all keystroke events
 
         return error;
}
ADMBoolean QueryDialog::QueryTrackProc(ADMItemRef inItem,ADMTrackerRef inTracker)
{
         ADMBooleancommandControlDown, notify = false;
 
         //checks if the(mac)COMMAND (win)CONTROL modifier is pressed
         commandControlDown =sADMTracker->TestModifier( inTracker, kADMMenuKeyDownModifier );
         //ctrl + enter时执行查询
         if(('\n' ==sADMTracker->GetCharacter(inTracker)) && commandControlDown)
         {
                   long length= sADMItem->GetTextLengthW(inItem);
                   if(length> 0)
                   {
                            ADMUnicode*txt = new ADMUnicode[length + 1];
                            memset(txt,0, 2 * (length + 1));
                            sADMItem->GetTextW(inItem, txt, length );
                            gPlugin->fQueryDialog->SearchArt(ai::UnicodeString(txt));
                            delete[]txt;
                   }
                   sADMItem->SetText(inItem,"");
                   sADMTracker->Abort(inTracker);
                   notify =true;
         }
         else
         {
                   notify =sADMItem->DefaultTrack( inItem, inTracker );
         }
         return notify;
}

查询部分我没有比较好的方案选择,于是傻傻的自己写了一个解析类Sql查询的模块。我的Sql定义为:条件 in图层,其中条件可以由多个一般判断表达式通过and or进行连接。如NAME=”China” in世界。解析时,使用的顺序是:

1.      预处理首尾空格裁剪,中间空格合并

2.      分离图层

3.      分析条件语句分析引号》分析圆括号》分析连接符》分析操作符》转换查询字符串链表到查询链接

查询链接即可用于图层内art遍历时筛选art了。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注常用软件Illustrator频道!

 


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved