2010/11/17 at 7:14 PM
ネタはあるのですけど、なかなか時間がなく、おお1年ぶり。今後は年に2回の更新を目標に頑張ります・・・。
さて、ここのところラスターファイルの扱いが多いのですが、なんでかワールドファイルがついておらず、2次メッシュコードがファイル名で「何とかなるでしょ」ってやつがありますです。はい。
[2次メッシュコード].jpg
まあ、うちの会社では年に2度あるかないかなのですが、広い世の中では年に千回ぐらいあるかもしれません。つきましてはスクリプトを書きましたので、おいておきます。
こんなのが、
こうなり
ます。
MakeWorldFileBy2ndMesh.py
#coding: utf-8 import re import os import sys from PIL import Image __author__="Toshihiro Hiraoka, AzukiMap K.K." __date__ ="$2010/11/16 16:05:17$" class JapanMesh2Extent(object): WIDTH_1ST_MESH = 1.0 HEIGHT_1ST_MESH = 1.0 / 1.5 WIDTH_2ND_MESH = WIDTH_1ST_MESH / 8 HEIGHT_2ND_MESH = HEIGHT_1ST_MESH / 8 WIDTH_3RD_MESH = WIDTH_2ND_MESH / 10 HEIGHT_3RD_MESH = HEIGHT_2ND_MESH / 10 def mesh2extent(self,mesh_code): mesh_code_str = str(mesh_code) if (len(mesh_code_str) == 4): return self.__firstmesh2extent(mesh_code_str) if (len(mesh_code_str) == 6): return self.__secondmesh2extent(mesh_code_str) if (len(mesh_code_str) == 8): return self.__thirdmesh2extent(mesh_code_str) raise AttributeError, "Mesh code is not collect length." def __firstmesh2extent(self, mesh_code): extent = MeshExtent() lon_string = mesh_code[2:4] lat_string = mesh_code[0:2] sw_lon = float(lon_string) + 100 sw_lat = float(lat_string) / 1.5 extent.south_west.lon = sw_lon extent.south_west.lat = sw_lat extent.north_west.lon = sw_lon extent.north_west.lat = sw_lat + self.HEIGHT_1ST_MESH extent.north_east.lon = sw_lon + self.WIDTH_1ST_MESH extent.north_east.lat = sw_lat + self.HEIGHT_1ST_MESH extent.south_east.lon = sw_lon + self.WIDTH_1ST_MESH extent.south_east.lat = sw_lat return extent; def __secondmesh2extent(self, mesh_code): extent = self.__firstmesh2extent(mesh_code) lon_string = mesh_code[5] lat_string = mesh_code[4] sw_lon = extent.south_west.lon + self.WIDTH_2ND_MESH * float(lon_string) sw_lat = extent.south_west.lat + self.HEIGHT_2ND_MESH * float(lat_string) extent.south_west.lon = sw_lon extent.south_west.lat = sw_lat extent.north_west.lon = sw_lon extent.north_west.lat = sw_lat + self.HEIGHT_2ND_MESH extent.north_east.lon = sw_lon + self.WIDTH_2ND_MESH extent.north_east.lat = sw_lat + self.HEIGHT_2ND_MESH extent.south_east.lon = sw_lon + self.WIDTH_2ND_MESH extent.south_east.lat = sw_lat return extent; def __thirdmesh2extent(self, mesh_code): extent = self.__secondmesh2extent(mesh_code) lon_string = mesh_code[7] lat_string = mesh_code[6] sw_lon = extent.south_west.lon + self.WIDTH_3RD_MESH * float(lon_string) sw_lat = extent.south_west.lat + self.HEIGHT_3RD_MESH * float(lat_string) extent.south_west.lon = sw_lon extent.south_west.lat = sw_lat extent.north_west.lon = sw_lon extent.north_west.lat = sw_lat + self.HEIGHT_3RD_MESH extent.north_east.lon = sw_lon + self.WIDTH_3RD_MESH extent.north_east.lat = sw_lat + self.HEIGHT_3RD_MESH extent.south_east.lon = sw_lon + self.WIDTH_3RD_MESH extent.south_east.lat = sw_lat return extent; class Point: lon = 0.0 lat = 0.0 def __init__(self): self.lon = 0.0 self.lat = 0.0 def __init__(self, lon, lat): self.lon = lon self.lat = lat class MeshExtent: north_west = Point(0,0) north_east = Point(0,0) south_west = Point(0,0) south_east = Point(0,0) def get_center(self): center_lon = ( self.north_west.lon + self.south_east.lon ) / 2 center_lat = ( self.north_west.lat + self.south_east.lon ) / 2 return Point(center_lon, center_lat) def get_width(self): return self.north_east.lon - self.north_west.lon def get_height(self): return self.north_east.lat - self.south_east.lat class WorldFileMaker: IMAGE_EXTENTIONS = '(\.jpg|\.jpeg|\.png|\.tif|\.tiff|\.bmp|\.gif)' __world_file_extention = "" __re_image_extentions = re.compile(IMAGE_EXTENTIONS) __mesh2extent = JapanMesh2Extent() def create_from_mesh_image_file(self, image_file, world_file_ext = '.wld'): meshfile = os.path.basename(image_file) meshcode = re.sub(self.__re_image_extentions, '', meshfile) if not meshcode.isdigit() : raise AttributeError, "file name is not mesh code" mesh_extent = self.__mesh2extent.mesh2extent(meshcode) self.create(image_file, mesh_extent, world_file_ext ) def create(self, image_file, extent, world_file_ext = '.wld'): self.__world_file_extention = world_file_ext image = Image.open(image_file) image_width = image.size[0] image_height = image.size[1] geo_width = extent.get_width() geo_height = extent.get_height() lon_per_pix = geo_width / image_width lat_per_pix = geo_height / image_height origin_lon = extent.north_west.lon + lon_per_pix / 2 origin_lat = extent.north_west.lat - lat_per_pix / 2 worldfile = self.__get_worldfilename(image_file) self.__save_worldfile(worldfile, origin_lon, origin_lat, lon_per_pix, lat_per_pix) def __get_worldfilename(self, image_file): return re.sub(self.__re_image_extentions, self.__world_file_extention, image_file) def __save_worldfile(self, worldfile, origin_lon, origin_lat, lon_per_pix, lat_per_pix): fp = open(worldfile, 'w') world_file_format = """%16.16f %s %s %16.16f %16.16f %16.16f """ content = world_file_format % (lon_per_pix, 0, 0, lat_per_pix * -1, origin_lon, origin_lat) fp.write(content) fp.flush() fp.close() if __name__ == "__main__": target_image_extention = '.jpg' world_file_extention = '.jgw' if len(sys.argv) != 2: raise Exception, "Set a mesh image directory." dir = sys.argv[1] if not os.path.exists(dir) : raise AttributeError, "Image directory is not correct." maker = WorldFileMaker() for root, dirs, files in os.walk(dir): for file in files: image_path = os.path.join(root, file) if file[-4:] == target_image_extention: image_path = os.path.join(root, file) print image_path maker.create_from_mesh_image_file(image_path, world_file_extention)
使い方
python MakeWorldFileBy2ndMesh.py [メッシュ画像のあるルートディレクトリ]
使用上の注意
2009/11/29 at 11:35 AM
基盤地図いろいろ使ってみましたが、”FG-GML-28-BldA25000-20080331-0016.xml”ファイルの1建物データにエラーがありました。
惜しくも、ポリゴンが閉じられていません。
<BldA gml:id="K17_3190169"> <fid>fgoid:10-00100-7-23-9119806</fid> <lfSpanFr gml:id="K17_3190169-1"> <gml:timePosition>2008-03-31</gml:timePosition> </lfSpanFr> <devDate gml:id="K17_3190169-2"> <gml:timePosition>2009-06-30</gml:timePosition> </devDate> <orgGILvl>25000</orgGILvl> <orgMDId>0-8</orgMDId> <area> <gml:Surface gml:id="K17_3190169-g" srsName="fguuid:jgd2000.bl"> <gml:patches> <gml:PolygonPatch> <gml:exterior> <gml:Ring> <gml:curveMember> <gml:Curve gml:id="K17_3190169-3"> <gml:segments> <gml:LineStringSegment> <gml:posList> 34.83565765 135.397553198 34.835658233 135.397545677 34.835655306 135.397551278 34.83565765 135.397553198 34.835658233 135.397545677 34.835717969 135.39743138 34.835701111 135.397429722 34.835661944 135.397497778 34.835658233 135.397545677 34.83565765 135.397553198 34.835656111 135.397573056 34.835673056 135.397573056 34.83569 135.397586667 34.835723611 135.397607222 34.83565765 135.397553198 34.835723611 135.397607222 34.835757434 135.397532229 34.835751944 135.397538889 34.835723611 135.397607222 34.835717969 135.39743138 34.835764922 135.397435999 34.83573 135.397408361 34.835717969 135.39743138 34.835764922 135.397435999 34.835791389 135.397456944 34.835768889 135.397436389 34.835764922 135.397435999 34.835757434 135.397532229 34.835768889 135.397518333 34.835791389 135.397456944 34.835757434 135.397532229 </gml:posList> </gml:LineStringSegment> </gml:segments> </gml:Curve> </gml:curveMember> </gml:Ring> </gml:exterior> </gml:PolygonPatch> </gml:patches> </gml:Surface> </area> <type>その他</type> <name></name> </BldA>
他のデータについては問題ないようです。
ちなみにこの場所は宝塚造形芸術大学とのこと。きっとすごい造形の建物があるのでしょう。
2009/11/28 at 5:28 PM
ありそうでない基盤地図のコンバーター。
もちろん、国土地理院からも出ているのですけど、一度ビュアーで展開する行程があって大量変換には向いていません。
DEMの変換ツールはTagchan博士が以下で公開されています。
http://www.tagchan.net/blog/2009/02/gsi_dem_gis.html
(便利!)
でも、ベクトルデータの変換はどうも見つかりません。基盤地図はGML3.2だから、GDALで変換できるでしょうと思いましたが、GDALのサポートフォーマットはGML2レベルまで。じゃ、新しいバージョンのPostGISならインポートできるかもしれないと、開発バージョンみてみるとGML3.1.1までのサポートとのこと。
http://postgis.refractions.net/documentation/manual-1.5SVN/ST_AsGML.html
GeoToolsでなんてのも考えましたが、GML3.2サポートはやはり微妙。
というわけで久方ぶりに変換スクリプトを書くことにしました。
シェープファイルに出力すると面倒なので、PostgreSQL/PostGIS環境にインサートするSQLをはき出すようにしてあります。Perlで書こうか、C#で書こうか、Rubyで書こうか、Javaで書こうか悩みましたが、一度も継承を使ったことないことを思い出してPythonで書きました。ヘビ文化を理解していないところがありますので、ちょっと変なところがあるかもしれません。許してください。
python kiban2pgsql.py [基盤地図GMLファイル|FG-GML-*****.xml] > output.sql
せっかくのデータです。多くの皆さんが利用できるようになることを願っております。
(それにしても道路中心線つけてほしいですね。はやく数値地図レベルまでき戻ってきてほしいです。)
kiban2pgsql.py
import sys import os.path __author__ = "Toshihiro Hiraoka, AzukiMap K.K." __date__ = "$2009/11/8 16:56:11$" srid = 4612 class Kiban2pgsql(object): def __init__(self, fHandler): self.fHandler = fHandler def Process(self): line = self.fHandler.readline() while line: """ find <BldA gml:id="K17_2061716"> """ if (line.startswith("<BldA")): PolygonParser(self.fHandler, line, "BldA", "building").Process() if (line.startswith("<AdmArea")): PolygonParser(self.fHandler, line, "AdmArea", "admin_area").Process() if (line.startswith("<RailCL")): LineParser(self.fHandler, line, "RailCL", "rail_center_line").Process() if (line.startswith("<Cstline")): LineParser(self.fHandler, line, "Cstline", "coast_line").Process() if (line.startswith("<AdmBdry")): LineParser(self.fHandler, line, "AdmBdry", "admin_boundary").Process() if (line.startswith("<RdEdg")): LineParser(self.fHandler, line, "RdEdg", "road_edge").Process() if (line.startswith("<WL")): LineParser(self.fHandler, line, "WL", "water_boundary").Process() if (line.startswith("<Cntr")): Contour(self.fHandler, line).Process() if (line.startswith("<AdmPt")): AdminPoint(self.fHandler, line, "AdmPt", "admin_point").Process() line = self.fHandler.readline() class Parser(object): def __init__(self, handler, topLine): self.id = "" self.fid = "" self.timePosition = "" self.name = "" self.type = "" self.fHandler = handler; self.topLine = topLine; self.linePoints = None; self.exterior = None self.interior = [] def SetId(self): """ <BldA gml:id="K17_2061716"> """ l = self.topLine.replace('>', '') l = l.replace('"', '') l = l.strip() words = l.split("=") self.id = words[1] def SetFid(self, line): """ <fid>fgoid:10-00100-7-23-5226929</fid>""" self.fid = self.GetElement(line) #print self.fid def SetTimePosition(self, line): """ <gml:timePosition>2009-06-30</gml:timePosition> """ self.timePosition = self.GetElement(line) #print self.timePosition def GetElement(self, line): """ <anything>return here</anything> """ l = line.replace("<", "|") l = l.replace(">", "|") words = l.split("|") return words[2] def GetPointsString(self, pointList): pointsStr = "" isFirst = True for p in pointList: if ( isFirst): isFirst = False else: pointsStr += "," pointsStr += p[0] + " " + p[1] return pointsStr class PointParser(Parser): def __init__(self, fHandler, topLine, tagName, tableName): Parser.__init__(self, fHandler, topLine) self.point = None self.endTag = "</%s" % tagName self.tableName = tableName def GetPointWKT(self): geomStr = "ST_GeomFromText('POINT(%s %s)',%d)" % ( self.point[0], self.point[1],srid) #print geomStr return geomStr def GetLonLat(self, line): """ <gml:pos>34.914059 133.054606</gml:pos> """ l = line.replace("<", "|") l = l.replace(">", "|") words = l.split("|") latlon = words[2].split(" ") """ The original order is lat-lon. """ return (latlon[1], latlon[0]) def Process(self): self.SetId() line = self.fHandler.readline() while line: if (line.startswith("<fid")): self.SetFid(line) if (line.startswith("<gml:timePosition")): self.SetTimePosition(line) if (line.startswith("<gml:pos")): self.point = self.GetLonLat(line) if (line.startswith("<type")): self.type = self.GetElement(line) if (line.startswith("<name")): self.name = self.GetElement(line) if (line.startswith(self.endTag)): self.Print() return line = self.fHandler.readline() def Print(self): sqlbase = "insert into %s (id, fid, time_position, type, name, filename, the_geom) values('%s','%s','%s','%s','%s','%s',%s);" geom = self.GetLinestringWKT() sql = sqlbase % (self.tableName, self.id, self.fid, self.timePosition, self.type, self.name, os.path.basename(self.fHandler.name), geom) print sql class LineParser(Parser): def __init__(self, fHandler, topLine, tagName, tableName): Parser.__init__(self, fHandler, topLine) self.endTag = "</%s" % tagName self.tableName = tableName def GetLinestringWKT(self): geomStr = "ST_GeomFromText('LINESTRING(%s)', %d)" % (self.GetPointsString(self.linePoints) , srid) #print geomStr return geomStr def Process(self): self.SetId() line = self.fHandler.readline() while line: if (line.startswith("<fid")): self.SetFid(line) if (line.startswith("<gml:timePosition")): self.SetTimePosition(line) if (line.startswith("<gml:posList")): self.linePoints = PositionList(self.fHandler).Process() if (line.startswith("<type")): self.type = self.GetElement(line) if (line.startswith("<name")): self.name = self.GetElement(line) if (line.startswith(self.endTag)): self.Print() return line = self.fHandler.readline() def Print(self): sqlbase = "insert into %s (id, fid, time_position, type, name, filename, the_geom) values('%s','%s','%s','%s','%s','%s',%s);" geom = self.GetLinestringWKT() sql = sqlbase % (self.tableName, self.id, self.fid, self.timePosition, self.type, self.name, os.path.basename(self.fHandler.name), geom) print sql class PolygonParser(Parser): def __init__(self, fHandler, topLine, tagName, tableName): Parser.__init__(self, fHandler, topLine) self.isExteriorLines = False self.isInteriorLines = False self.endTag = "</%s" % tagName self.tableName = tableName def GetExteriorPoints(self): self.exterior = PositionList(self.fHandler).Process() #print self.exterior def GetInteriorPoints(self): self.interior.append(PositionList(self.fHandler)) def GetGeometryString(self): exteriorStr = "(" + self.GetPointsString(self.exterior) + ")" interiorStr = "" isFirst = True for pointList in self.interior: interiorStr += "," interiorStr += "(" + self.GetPointsString(pointList) + ")" geomStr = "POLYGON(" + exteriorStr if (interiorStr != ""): geomStr += interiorStr geomStr += ")" return geomStr def GetPolygonWKT(self): exteriorStr = "(" + self.GetPointsString(self.exterior) + ")" interiorStr = "" isFirst = True for pointList in self.interior: interiorStr += "," interiorStr += "(" + self.GetPointsString(pointList) + ")" geomStr = "ST_GeomFromText('POLYGON(%s" % exteriorStr if (interiorStr != ""): geomStr += interiorStr geomStr += ")',%d)" % srid return geomStr def Process(self): self.SetId() line = self.fHandler.readline() while line: if (line.startswith("<fid")): self.SetFid(line) if (line.startswith("<gml:timePosition")): self.SetTimePosition(line) if (line.startswith("<gml:exterior")): self.isExteriorLines = True if (line.startswith("</gml:exterior")): self.isExteriorLines = False if (line.startswith("<gml:interior")): self.isInteriorLines = True if (line.startswith("</gml:interior")): self.isInteriorLines = False if (line.startswith("<gml:posList")): if ( self.isExteriorLines ): self.GetExteriorPoints() if (self.isInteriorLines): self.GetInteriorPoints if (line.startswith("<type")): self.type = self.GetElement(line) if (line.startswith("<name")): self.name = self.GetElement(line) if (line.startswith(self.endTag)): self.Print() return line = self.fHandler.readline() def Print(self): sqlbase = "insert into %s (id, fid, time_position, type, name, filename, the_geom) values('%s','%s','%s','%s','%s','%s',%s);" geom = self.GetPolygonWKT() sql = sqlbase % (self.tableName, self.id, self.fid, self.timePosition, self.type, self.name, os.path.basename(self.fHandler.name), geom) print sql class PositionList(object): def __init__(self, fHandler): self.fHandler = fHandler self.points = [] def GetLonLat(self, line): """ 33.184039444 131.072192778\n """ line = line.strip() latlon = line.split(" ") """ The original order is lat-lon. """ return (latlon[1], latlon[0]) def Process(self): line = self.fHandler.readline() while line: if ( line.startswith("</gml:posList")): return self.points self.points.append(self.GetLonLat(line)) line = self.fHandler.readline() class PointLine(object): def GetLonLat(self, line): """ <gml:pos>34.914059 133.054606</gml:pos> """ l = line.replace("<", "|") l = l.replace(">", "|") words = l.split("|") latlon = words[2].split(" ") """ The original order is lat-lon. """ return (latlon[1], latlon[0]) class AdminPoint(PointParser): def __init__(self, fHandler, topLine, tagName, tableName): PointParser.__init__(self, fHandler, topLine, tagName, tableName) self.adminCode = "" def Process(self): self.SetId() line = self.fHandler.readline() while line: if (line.startswith("<fid")): self.SetFid(line) if (line.startswith("<gml:timePosition")): self.SetTimePosition(line) if (line.startswith("<gml:pos")): self.point = self.GetLonLat(line) if (line.startswith("<type")): self.type = self.GetElement(line) if (line.startswith("<name")): self.name = self.GetElement(line) if (line.startswith("<admCode")): self.adminCode = self.GetElement(line) if (line.startswith(self.endTag)): self.Print() return line = self.fHandler.readline() def Print(self): sqlbase = "insert into %s (id, fid, code, time_position, type, name, filename, the_geom) values('%s','%s','%s','%s','%s','%s','%s',%s);" geom = self.GetPointWKT() sql = sqlbase % (self.tableName, self.id, self.fid, self.adminCode, self.timePosition, self.type, self.name, os.path.basename(self.fHandler.name), geom) print sql class Contour(LineParser): def __init__(self, fHandler, topLine): LineParser.__init__(self, fHandler, topLine, "Cntr", "countour") self.altitude = None def Process(self): self.SetId() line = self.fHandler.readline() while line: if (line.startswith("<fid")): self.SetFid(line) if (line.startswith("<gml:timePosition")): self.SetTimePosition(line) if (line.startswith("<gml:posList")): self.linePoints = PositionList(self.fHandler).Process() if (line.startswith("<type")): self.type = self.GetElement(line) if (line.startswith("<alti")): self.altitude = self.GetElement(line) if (line.startswith("</Cntr")): self.Print() return line = self.fHandler.readline() def Print(self): sqlbase = "insert into %s (id, fid, time_position, type, altitude, filename, the_geom) values('%s','%s','%s','%s',%s,'%s',%s);" geom = self.GetLinestringWKT() sql = sqlbase % ("contour", self.id, self.fid, self.timePosition, self.type, self.altitude, os.path.basename(self.fHandler.name), geom) print sql def usage(): print "Usage: python kiban2pgsql.py [kiban_file_name].xml\n" if __name__ == "__main__": argv = sys.argv if len(argv) != 2: usage() sys.exit(0) target = open(argv[1]) if target is None: print "file: " + argv[1] + " cannot open.\n" sys.exit(0) kiban2pgsql = Kiban2pgsql(target) kiban2pgsql.Process()
createKibanTables.sql
DROP TABLE "building"; DROP TABLE "admin_area"; DROP TABLE "rail_center_line"; DROP TABLE "coast_line"; DROP TABLE "admin_boundary"; DROP TABLE "road_edge"; DROP TABLE "water_boundary"; DROP TABLE "contour"; DROP TABLE "admin_point"; CREATE TABLE "building" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(28), "time_position" date, "type" varchar(6), "name" varchar(1), "filename" varchar(42) ); SELECT AddGeometryColumn('','building','the_geom','4326','POLYGON',2); CREATE TABLE "admin_area" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(24), "time_position" date, "type" varchar(9), "name" varchar(16), "filename" varchar(42) ); SELECT AddGeometryColumn('','admin_area','the_geom','4326','POLYGON',2); CREATE TABLE "rail_center_line" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(26), "time_position" date, "type" varchar(8), "name" varchar(1), "filename" varchar(42) ); SELECT AddGeometryColumn('','rail_center_line','the_geom','4326','LINESTRING',2); CREATE TABLE "coast_line" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(26), "time_position" date, "type" varchar(3), "name" varchar(1), "filename" varchar(42) ); SELECT AddGeometryColumn('','coast_line','the_geom','4326','LINESTRING',2); CREATE TABLE "admin_boundary" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(25), "time_position" date, "type" varchar(10), "name" varchar(1), "filename" varchar(42) ); SELECT AddGeometryColumn('','admin_boundary','the_geom','4326','LINESTRING',2); CREATE TABLE "road_edge" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(28), "time_position" date, "type" varchar(8), "name" varchar(1), "filename" varchar(42) ); SELECT AddGeometryColumn('','road_edge','the_geom','4326','LINESTRING',2); CREATE TABLE "water_boundary" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(27), "time_position" date, "type" varchar(7), "name" varchar(1), "filename" varchar(42) ); SELECT AddGeometryColumn('','water_boundary','the_geom','4326','LINESTRING',2); CREATE TABLE "contour" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(27), "time_position" date, "type" varchar(5), "altitude" float, "filename" varchar(42) ); SELECT AddGeometryColumn('','contour','the_geom','4326','LINESTRING',2); CREATE TABLE "admin_point" (gid serial PRIMARY KEY, "id" varchar(12), "fid" varchar(24), "code" varchar(6), "time_position" date, "type" varchar(16), "name" varchar(16), "filename" varchar(42) ); SELECT AddGeometryColumn('','admin_point','the_geom','4326','POINT',2);
2009/11/22 at 11:18 PM
何とかうちの会社も皆様のおかげさまで2年持ちました。
そろそろお返しをさせていただきたく、弊社の技術情報などを公開させていただきます。
名実ともにまめ会社で、できないことは数限りないですが、大きな会社ではできないことを出せていけたらと思います。