Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архив1 / docx55 / note1.docx
Скачиваний:
19
Добавлен:
01.08.2013
Размер:
138.2 Кб
Скачать

Оглавление

ВВЕДЕНИЕ 2

1.Основные принципы построения компонента просмотра 3

1.1.Понятие геоинформационной системы 4

1.2.Возможности геоинформационной системы 4

1.3.Понятие геоинформационных форматов *.mid, *.mif 4

2.Проектирование компонента просмотра SCs текстов 6

2.1.Выбор средств проектирования 6

2.2.Определение основных требований к разрабатываемому компоненту 6

3.Реализация компонента просмотра SCs текстов 8

3.1.Реализация компонента просмотра mid/mif форматов 8

3.2.Реализация парсера mid/mif форматов 19

4.Расчётная работа на тему «Документирование web-ориентированной реализации интерпретатора sc-моделей» 23

4.1 Введение 23

4.2 Общая структура 24

4.3 Программная реализация sc-памяти 25

4.4 Программная реализация интерпретатора языка SCp 26

4.5 Программная реализация компонентов ядра пользовательских интерфейсов 27

29

4.6 Компоненты ядра пользовательского интерфейса 29

4.7. Базовый набор операций 30

4.8 Описание принципов организации диалога системы с пользователем 31

32

4.9 Режим диалога с использованием SCn-кода 33

4.10 Режим диалога с использованием SCg-кода 34

4.11 Общая схема взаимодействия подсистем 35

4.12 Разработчикам 36

ЗАКЛЮЧЕНИЕ 37

Введение

На сегодняшний день, информация и данных хранятся в очень большом количестве форматов. Эти форматы в своём большинстве не предназначены для непосредственного восприятия их человеком, а просто служат удобной формой её хранения, с целью дальнейшей обработки, редактирования, визуализации и т.п. Поэтому, актуальной проблемой в настоящее время является проблема отображения их в той форме, в которой пользователю с ней будет "удобно" работать.

Программные системы, интерфейсы которых предоставляют конечному пользователю большое количество возможностей и, в то же время, не "перегруженные" сложными вариантами использования этих возможностей, удобные пользователю, способные настраиваться и расширяться под конкретные нужды пользователя, имеют большое преимущество даже перед теми системами, которым они уступают по функциональным возможностям.

Из всего вышесказанного следует, что при разработке различных систем, проектированию пользовательского интерфейса стоит уделять внимание не меньшее, чем для разработки функциональности системы, а, возможно, для некоторых систем, этому компоненту системы должно быть уделено основное время проектирования и разработки.

Основной целью данного курсового проекта является адаптация компонента просмотра mid/mifформатов под последнюю версию ядра ПИ.

Данную цель можно разбить на следующие подцели:

  • Проанализировать существующие инструментарии для создания компонента просмотра на языке программирования Python

  • Выбрать инструментарий для создания компонента просмотра mid/mifформатов

  • Реализовать парсер mid/mif форматов

  • Реализовать компонент просмотра mid/mifформатов

В рамках курсовой работы ставятся следующие задачи:

  • Разработать компонент просмотра mid/mifформатов

  • Адаптировать компонент просмотра данных форматов

  • Определить направления дальнейшего развития разработанного компонента

  1. Основные принципы построения компонента просмотра

    1. Понятие геоинформационной системы

Геоинформационная система - система сбора, хранения, анализа и графической визуализации пространственных данных и связанной с ними информацией о необходимых объектах.

Термин также используется в более узком смысле - ГИС как инструмент позволяющий пользователям искать, анализировать и редактировать цифровые карты, а также дополнительную информацию об объектах, например высоту здания, адрес, количество жильцов.

    1. Возможности геоинформационной системы

Геоинформационные системы включают в себя возможности:

  • систем управления базами данных;

  • редакторов растровой и векторной графики;

  • редакторов аналитических средств;

Применяются в:

  • Картографии;

  • Геологии;

  • Метеорологии;

  • Замлеустройстве;

  • Экологии;

  • Транспорте;

  • Экономике;

  • Обороне и др.

    1. Понятие геоинформационных форматов *.mid, *.mif

Mif/mid– открытый текстовый обменный формат для геоинформационных систем. Состоит и двух файлов:

.mif– описание проекций, трансформаций и прочих дополнительных сведений, а, главное, перечень пространственных объектов (точки, линии, полигоны) с их координатами.

.mid– одноименный сmifфайл, в котором для каждого пространственного объекта, описанного вmif, приводится строка с семантическими данными.

  1. Проектирование компонента просмотра SCs текстов

    1. Выбор средств проектирования

Вопрос выбора подхода проектирования и средств разработки является основополагающим для всего жизненного цикла разрабатываемой системы. Он определяет не только количество материальных и временных ресурсов, затраченных на разработку, но и дальнейшую работоспособность системы.

В первую очередь, для реализации поставленных целей необходимо написать парсер для mid/mifформатов.

Синтаксический анализатор— это программа или часть программы, выполняющая синтаксический анализ.

Cинтаксический анализ— это процесс сопоставления линейной последовательности лексем (слов, токенов) языка с его формальной грамматикой. Результатом обычно является дерево разбора (синтаксическое дерево). Обычно применяется совместно с лексическим анализом.

Прежде всего, необходимо определится с инструментарием для написания синтаксического анализатора.

Выбранный анализатор должен обладать следующими свойствами:

  • возможность генерации программного кода в язык Python

  • наличие графических средств разработки

  • наличие полной и доступной документации

    1. Определение основных требований к разрабатываемому компоненту

Определим основные требования, предъявляемые к разрабатываемому компоненту:

  • Разрабатываемый компонент должен иметь возможность распознавать mid/mifформаты

  • Разрабатываемый компонент должен иметь возможность отображать данные форматы

  • Разрабатываемый компонент должен иметь возможность редактирования и прорисовки данных форматов

  1. Реализация компонента просмотра SCs текстов

    1. Реализация компонента просмотра mid/mif форматов

Приведём пример фрагмента реализации просмотра mid/mifформатов

class MapViewer(BaseModeLogic):

def __init__(self):

BaseModeLogic.__init__(self)

self.sceneNodeRect = render_engine.SceneManager.createSceneNode()

self.rect = None

self._createRect()

self.material = None

self.texture = None

self.origin = [0.5, 0.5]

self.field = None

self.drawer = None

self.mapSurface = None

self.layerData = []

self.zoomRectCorners = [[0, 0], [0, 0]]

self.tex_size = (1024, 1024)

self.appendMode(ois.KC_V, map_modes.MapViewMode(self))

self.switchMode(ois.KC_V)

def __del__(self):

BaseModeLogic.__del__(self)

def delete(self):

"""Deletion message

"""

BaseModeLogic.delete(self)

def _setSheet(self, _sheet):

BaseModeLogic._setSheet(self, _sheet)

_sheet.eventRootChanged = self._onRoot

self._createFieldFromContent()

self._createMaterial()

self.rect.setMaterial(self.getMaterialName())

self._redraw()

def _onRoot(self, _isRoot):

"""Notification on sheet root state changing

"""

if _isRoot:

self.controlPanel()

render_engine.SceneNode.addChild(self._getSheet().sceneNodeChilds, self.sceneNodeRect)

else:

render_engine.SceneNode.removeChild(self._getSheet().sceneNodeChilds, self.sceneNodeRect)

def _createRect(self):

""" Creates rectangle surface for root mode

"""

# FIXME: make thread safe

self.rect = ogre.Rectangle2D(True)

self.rect.setCorners(-1.0, 1.0, 1.0, -1.0)

self.rect.setRenderQueueGroup(ogre.RENDER_QUEUE_8)

self.rect.setBoundingBox(ogre.AxisAlignedBox(ogre.Vector3(-100000.0, -100000.0, -100000.0), ogre.Vector3(100000.0, 100000.0, 100000.0)))

self.sceneNodeRect.attachObject(self.rect)

def _destroyRect(self):

""" Destroys rectangle surface for root mode

"""

self.rect = None

# FIXME: scene node removing

def getMaterialName(self):

return str(self) + "material"

def _createMaterial(self):

self.material = ogre.MaterialManager.getSingleton().create(self.getMaterialName(), env.resource_group)

mpass = self.material.getTechnique(0).getPass(0)

mpass.setLightingEnabled(True)

mpass.setDiffuse(0.0, 1.0, 0.0, 1.0)

tex_name = str(self) + "tex"

self.texture = ogre.TextureManager.getSingleton().createManual(tex_name, env.resource_group,

ogre.TEX_TYPE_2D, self.tex_size[0], self.tex_size[1], 32,

5, ogre.PixelFormat.PF_A8R8G8B8,

ogre.TU_DYNAMIC_WRITE_ONLY_DISCARDABLE)

tus = mpass.createTextureUnitState(tex_name)

def _layerClick(self, list, pvt):

ind = list.getIndexSelected()

dir(list)

if ind >= 0 and ind < list.getItemCount():

name = list.getItemNameAt(ind)

for data in self.layerData:

layer = data["layer"]

itemName = unicode(name).split()[1]

list.setItemNameAt(ind, itemName)

if itemName == unicode(layer.name):

layer.visible = not layer.visible

itemName = {True:'O', False:'X'}[layer.visible] + " " + itemName

list.setItemNameAt(ind, itemName)

pref = ""

if not layer.visible:

pref = "in"

if not data["drawn"]:

self.drawer.drawIt(self.scaleManager.scale, self.layerData)

buff = self.texture.getBuffer()

lock = buff.lock(0, buff.getSizeInBytes(), ogre.HardwareBuffer.HBL_NORMAL)

self.drawMap()

buff.unlock()

break

def controlPanel(self):

gui = render_engine._gui

#self.x, self.y = render_engine._ogreRenderWindow.getWidth(), render_engine._ogreRenderWindow.getHeight()

wid = 200

hei = 400

horOffset = 5

window = gui.createWidgetT("Window", "Window", mygui.IntCoord(10, 10, wid + 10, hei + 10), mygui.Align(), "Overlapped", '')

layerList = window.createWidgetT("List", "List", mygui.IntCoord(horOffset, 20, wid - 2 * horOffset, hei - 60), mygui.Align())

layerList.subscribeEventMouseItemActivate(self,'_layerClick')

for layer in self.field.layers:

layerList.addItem("O " + unicode(layer.name))

return

#list = self.gui.createWidgetT("List", "List", mygui.IntCoord(20, 270, 140, 100), mygui.Align())

#list = self.gui.createWidgetT("List", "List", mygui.IntCoord(20, 270, 140, 100), mygui.Align())

begin = (self.x - self.butWidth*self.butAmount)

begin = begin/2

self.wpanel = self.gui.createWidgetT("Widget", "Panel", mygui.IntCoord(1, self.y - 40, self.x, 40), mygui.Align(), "Popup", '')

self.wpanel.setAlpha(1)

self.slider = self.wpanel.createWidgetT("HScroll", "HSlider", mygui.IntCoord(50, 5, 700, 5), mygui.Align())

self.slider.setScrollRange(100)

self.stopbut = self.wpanel.createWidgetT("Button", "Button", mygui.IntCoord(begin, 15, self.butWidth, self.butHeight), mygui.Align())

self.stopbut.setCaption("Stop")

self.stopbut.subscribeEventMouseButtonClick(self,'_stop')

begin = begin + self.butWidth

self.backbut = self.wpanel.createWidgetT("Button", "Button", mygui.IntCoord(begin, 15, self.butWidth, self.butHeight), mygui.Align())

self.backbut.setCaption("Back")

begin = begin + self.butWidth

self.plbut = self.wpanel.createWidgetT("Button", "Button", mygui.IntCoord(begin, 15, self.butWidth, self.butHeight), mygui.Align())

if self.audioPlayer.isPlaying():

self.plbut.setCaption("Pause")

else:

self.plbut.setCaption("Play")

self.plbut.subscribeEventMouseButtonClick(self,'_play_pause')

begin = begin + self.butWidth

self.forwbut = self.wpanel.createWidgetT("Button", "Button", mygui.IntCoord(begin, 15, self.butWidth, self.butHeight), mygui.Align())

self.forwbut.setCaption("Forward")

begin = begin + self.butWidth

self.volslider = self.wpanel.createWidgetT("HScroll", "HSlider", mygui.IntCoord(begin, 23, self.butWidth, 5), mygui.Align())

self.volslider.setScrollRange(100)

self.panel = True

def drawMap(self):

# setting variables SIZEX and SIZEY to the size of field in pixels

factor = self.scaleManager.getFactor()

SIZEX = SIZEY = self.drawer.standardConstrainPx * factor

self.ctx.set_source_rgba (1, 1, 1, 1)

self.ctx.rectangle(0, 0, SIZEX, SIZEY)

self.ctx.fill()

for data in self.layerData:

if data["layer"].visible:

self.ctx.set_source_surface(data["surface"])

self.ctx.paint()

self.ctx.set_source_surface(data["selected-surface"])

self.ctx.paint()

def screenToMap(self, pt):

tx, ty = 0, 0

factor = self.scaleManager.getFactor()

tx = (factor - 1) * self.origin[0]

ty = (factor - 1) * self.origin[1]

mx = pt[0] / render_engine.Window.width

my = pt[1] / render_engine.Window.height

res = [(tx + mx) / factor,

(ty + my) / factor]

return res

def zoomIn(self):

return self.scaleManager.increaseScale()

def zoomOut(self):

return self.scaleManager.decreaseScale()

def _redraw(self):

"""

"""

for data in self.layerData:

data["drawn"] = False

"""Redraws map

"""

buff = self.texture.getBuffer()

lock = buff.lock(0, buff.getSizeInBytes(), ogre.HardwareBuffer.HBL_NORMAL)

width = self.tex_size[0]

height = self.tex_size[1]

import ctypes, cairo, math

# creating buffer in memory from locked data

data_buff = (ctypes.c_uint8 * (4 * width * height)).from_address(ogre.CastInt(lock)) # allocate a buffer class

# creating surface for buffer in memory

surface = cairo.ImageSurface.create_for_data(data_buff, cairo.FORMAT_ARGB32, width, height)

# creating context for drawing

self.ctx = cairo.Context(surface)

# adjusting position to the center point

tx, ty = self.getTranslation()

#if self.mapSurface:

# self.mapSurface.finish()

# creating a surface for map only

for data in self.layerData:

layerSurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)

# creating a context for it

layerCtx = cairo.Context(layerSurface)

layerCtx.translate(tx, ty)

layerCtx.rectangle(-tx, -ty,

width, height)

layerCtx.clip()

selSurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)

# creating a context for it

selCtx = cairo.Context(selSurface)

selCtx.translate(tx, ty)

selCtx.rectangle(-tx, -ty,

width, height)

selCtx.clip()

data["surface"] = layerSurface

data["context"] = layerCtx

data["selected-surface"] = selSurface

data["selected-context"] = selCtx

# drawing to a map context

self.drawer.drawIt(self.scaleManager.scale, self.layerData)

self.drawMap()

buff.unlock()

def setOrigin(self, pt):

self.origin[0] = pt[0]

self.origin[1] = pt[1]

def moveOrigin(self, hor, ver):

factor = self.drawer.manager.getFactor()

if hor != 0:

self.origin[0] += .1 * hor / factor

if ver != 0:

self.origin[1] += .1 * ver / factor

print "origin: " + str(self.origin)

def drawLayerSelection(self, layer):

for data in self.layerData:

if data["layer"] == layer:

width = self.tex_size[0]

height = self.tex_size[1]

selSurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)

# creating a context for it

selCtx = cairo.Context(selSurface)

tx, ty = self.getTranslation()

selCtx.translate(tx, ty)

selCtx.rectangle(-tx, -ty,

width, height)

selCtx.clip()

data["selected-surface"] = selSurface

data["selected-context"] = selCtx

buff = self.texture.getBuffer()

lock = buff.lock(0, buff.getSizeInBytes(), ogre.HardwareBuffer.HBL_NORMAL)

self.drawer.drawLayerData(data, True)

self.drawMap()

buff.unlock()

break;

def _createFieldFromContent(self):

"""Creates map field for drawing from node content

"""

data = self._getContent()

if data is None: return

parser = map_utils.map_parser.LayersParser()

#FIXME delete line with \n

list = data.split('\r\n')

parser.parseLayers(list)

self.drawer = fieldDrawer.FieldDrawer()

#self.field = field.Field()

self.drawer.field = field.Field()

self.scaleManager = self.drawer.manager

transformScale = (0.5, 1)

#classifier = self.field.classifier

self.drawer.standardConstrainPx = self.tex_size[1]

#layer = field.Layer()

width = self.tex_size[0]

height = self.tex_size[1]

layerNum = 0

for lay in parser.layers:

layer = field.Layer()

layer.name = parser.layer_name[layerNum]

layerNum += 1

for i in range(len(lay.mif_data)):

if lay.object_type[i] == 'REGION':

region = field.PolygonItem(lay.mif_data[i], transformScale)

region.type = int(lay.mid_data[i]['CODE'])

region.setAttributes(lay.mid_data[i])

layer.addItem(region)

elif lay.object_type[i] == 'LINE':

line = field.LineItem(lay.mif_data[i], transformScale)

line.type = int(lay.mid_data[i]['CODE'])

line.setAttributes(lay.mid_data[i])

layer.addItem(line)

elif lay.object_type[i] == 'PLINE':

pline = field.LineItem(lay.mif_data[i], transformScale)

pline.type = int(lay.mid_data[i]['CODE'])

pline.setAttributes(lay.mid_data[i])

#FIXME change LineItem (draw one part)

layer.addItem(pline)

elif lay.object_type[i] == 'POINT':

pass

self.drawer.field.addLayer(layer)

self.field = self.drawer.standardField = self.drawer.createStandardField()

#self.field

#print "lrs: " + str(self.field.layers);

for layer in self.field.layers:

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)

ctx = cairo.Context(surface)

self.layerData.append({"layer": layer, "surface": surface, "context": ctx, "drawn": False})

def _getContent(self):

"""Returns node content

"""

session = core.Kernel.session()

_addr = self._getSheet()._getScAddr()

if _addr is not None:

_cont = session.get_content_const(_addr)

assert _cont is not None

_cont_data = _cont.convertToCont()

data = _cont.get_data(_cont_data.d.size)

#print data

return data

return None

    1. Реализация парсера mid/mif форматов

Для написания выбран язык программирования Python. В инструментарии уже имеется большое количество классов с необходимой нам функциональностью. За основу мы будем брать имеющиеся классы и расширять их функциональность.

def mifParser(self, mifData):

self.setMifVersion(int(re.findall(r'\d+', mifData[0])[0]))

self.setMifDelimiter(mifData[1].strip()[-2])

items = re.findall(r'(\d+), *(\d+)', mifData[2])[0]

self.setMifCoord_Projection(int(items[0]), int(items[1]))

columns = []

regions = []

readLine = 3

while readLine < len(mifData):

if 'COLUMNS' in mifData[readLine]:

columns_num = int(re.findall(r'\d+', mifData[readLine])[0])

for i in range(columns_num):

readLine = readLine + 1

column_name, column_value = mifData[readLine].strip().split()

columns.append((column_name, column_value))

self.setMifColumns(columns)

if 'REGION' in mifData[readLine]:

region_num = int(re.findall(r'\d+', mifData[readLine])[0])

region = []

readLine = readLine + 1

while 'BRUSH' not in mifData[readLine]:

points = []

lines_num = int(re.findall(r'\d+', mifData[readLine])[0])

for i in range(lines_num):

readLine = readLine + 1

x, y = mifData[readLine].strip().split()

points.append([float(x), float(y)])

region.append(points)

readLine = readLine + 1

self.setMifData(region)

self.object_type.append('REGION')

if 'LINE' in mifData[readLine][0:4] :

x1,y1,x2,y2 = mifData[readLine][4:len(mifData[readLine])].strip().split()

line = []

points = []

points.append([float(x1), float(y1)])

points.append([float(x2), float(y2)])

line.append(points)

self.setMifData(line)

self.object_type.append('LINE')

if 'PLINE' in mifData[readLine]:

pline = []

points = []

if 'MULTIPLE' in mifData[readLine]:

num_plines = int(mifData[readLine][14:len(mifData[readLine])].strip())

while num_plines > 0:

points = []

readLine = readLine + 1

num_points = mifData[readLine].strip()

for i in range(int(num_points)):

readLine = readLine + 1

x, y = mifData[readLine].strip().split()

points.append([float(x), float(y)])

pline.append(points)

num_plines = num_plines - 1

else:

num_points = mifData[readLine][5:len(mifData[readLine])].strip()

for i in range(int(num_points)):

readLine = readLine + 1

x, y = mifData[readLine].strip().split()

points.append([float(x), float(y)])

pline.append(points)

self.setMifData(pline)

self.object_type.append('PLINE')

if 'POINT' in mifData[readLine]:

point = []

points = []

x,y = mifData[readLine][5:len(mifData[readLine])].strip().split()

points.append([float(x), float(y)])

point.append(points)

self.setMifData(point)

self.object_type.append('POINT')

readLine = readLine+1

def midParser(self, midData):

for line in midData:

items = line.split(',')

if(len(items[-1])>2):

if '"' in items[-1][-3]:

items[-2] = items[-2] + "," + items[-1]

items = items [:-1]

self.setMidData(items)

else:

self.setMidData(items)

def parseFromFiles(self, mifPath = "", midPath = ""):

mifFile = codecs.open(mifPath, mode='r')#, encoding='cp1251')

mifData = mifFile.readlines()

mifFile.close()

self.mifParser(mifData)

midFile = codecs.open(midPath, mode='r')#, encoding='cp1251')

midData = midFile.readlines()

midFile.close()

self.midParser(midData)

def parseFromString(self, data):

for i in range(len(data)):

if '#mif' in data[i]:

f = i+1

if '#mid' in data[i]:

d = i+1

self.mifParser(data[f:d-1])

self.midParser(data[d:])

  1. Расчётная работа на тему «Документирование web-ориентированной реализации интерпретатора sc-моделей»

Соседние файлы в папке docx55